apass-opensdk-hugong 1.0.5 → 1.0.7

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.
@@ -0,0 +1,86 @@
1
+ // Object_.d.ts
2
+ export = Object_;
3
+
4
+ declare class Object_ {
5
+ constructor(hg: any);
6
+
7
+ /* ===== 查询 ===== */
8
+
9
+ /**
10
+ * 清空表中满足条件的数据
11
+ * @param table 表名
12
+ * @param where 条件对象;省略时全部清空
13
+ */
14
+ clearData(table: string, where?: any): Promise<void>;
15
+
16
+ /**
17
+ * 查询列表
18
+ * @param table 表名
19
+ * @param field 需要返回的字段,默认 ['_id','_name']
20
+ * @param where 过滤条件
21
+ * @param callback 每批记录回调;提供时方法返回 void
22
+ * @param orderby 排序字段,默认 '_id'
23
+ * @returns 无 callback 时返回全部记录
24
+ */
25
+ findList<T = any>(
26
+ table: string,
27
+ field?: string[] | null,
28
+ where?: any,
29
+ callback?: (records: T[]) => Promise<void> | void,
30
+ orderby?: string
31
+ ): Promise<T[] | void>;
32
+
33
+ /**
34
+ * 查询单条记录
35
+ */
36
+ findOne<T = any>(
37
+ table: string,
38
+ field?: string[] | null,
39
+ where?: any
40
+ ): Promise<T | null>;
41
+
42
+ /**
43
+ * 根据主键查询单条记录
44
+ */
45
+ findOneById<T = any>(
46
+ table: string,
47
+ id: string | number,
48
+ field?: string[] | null
49
+ ): Promise<T | null>;
50
+
51
+ /* ===== 写入 ===== */
52
+
53
+ /**
54
+ * 批量创建
55
+ */
56
+ batchCreate<T = any>(table: string, list: T[]): Promise<any>;
57
+
58
+ /**
59
+ * 创建单条记录
60
+ */
61
+ create<T = any>(table: string, data: T): Promise<any>;
62
+
63
+ /* ===== 更新 ===== */
64
+
65
+ /**
66
+ * 批量更新
67
+ */
68
+ batchUpdate<T = any>(table: string, list: T[]): Promise<any>;
69
+
70
+ /**
71
+ * 更新单条记录
72
+ */
73
+ update<T = any>(table: string, data: T): Promise<any>;
74
+
75
+ /* ===== 删除 ===== */
76
+
77
+ /**
78
+ * 删除单条记录(按 _id)
79
+ */
80
+ delete(table: string, _id: string | number): Promise<any>;
81
+
82
+ /**
83
+ * 批量删除(按 _ids)
84
+ */
85
+ delete(table: string, _ids: (string | number)[]): Promise<any>;
86
+ }
package/apass/object_.js CHANGED
@@ -1,69 +1,186 @@
1
- class Object_{
1
+ class Object_ {
2
2
  #hg = null
3
- constructor(hg){
3
+ constructor(hg) {
4
4
  this.#hg = hg
5
5
  }
6
6
 
7
- async clearData(table,id){
8
- await application.data.object(table).select('_id').where({_id: id ? id : application.operator.gte(0)}).findStream(async records=>{
7
+ /**
8
+ * 清空表中满足条件的数据
9
+ * @param table 表名
10
+ * @param where 条件对象;省略时全部清空
11
+ * @param useSystemAuth 是否使用系统权限;默认 false
12
+ */
13
+ async clearData(table, where, useSystemAuth = false) {
14
+ const object = application.data.object(table).select('_id').where(where ? where : { _id: application.operator.gte(0) })
15
+ if (useSystemAuth) {
16
+ object.useSystemAuth()
17
+ }
18
+ await object.findStream(async records => {
9
19
  this.#hg.log4('clear data len', records.length)
10
- await application.data.object(table).batchDelete(records.map(it=>({_id: it._id})))
20
+ const object = application.data.object(table)
21
+ if (useSystemAuth) {
22
+ object.useSystemAuth()
23
+ }
24
+ await object.batchDelete(records.map(it => ({ _id: it._id })))
11
25
  })
12
26
  }
13
27
 
14
- async findList(table,field,where,callback){
28
+ /**
29
+ * 查询列表
30
+ * @param table 表名
31
+ * @param field 需要返回的字段,默认 ['_id','_name']
32
+ * @param where 过滤条件
33
+ * @param callback 每批记录回调;提供时方法返回 void
34
+ * @param orderby 排序字段,默认 '_id'
35
+ * @param useSystemAuth 是否使用系统权限;默认 false
36
+ * @returns 无 callback 时返回全部记录
37
+ */
38
+ async findList(table, fields, where, callback, orderby, useSystemAuth = false) {
15
39
  const list = []
16
- await application.data.object(table).select(field || ['_id','_name']).where(where || {_id : application.operator.gte(0)}).findStream(async records=>{
17
- if(callback){
18
- this.#hg.log4('find all len', list.length)
40
+ const object = application.data.object(table).select(fields || ['_id', '_name']).where(where || { _id: application.operator.gte(0) }).orderByDesc(orderby || '_id')
41
+ if (useSystemAuth) {
42
+ object.useSystemAuth()
43
+ }
44
+ await object.findStream(async records => {
45
+ if (callback) {
46
+ this.#hg.log4('find all len', records.length)
19
47
  await callback(records)
20
- }else{
21
- this.#hg.log4('find all size', list.length)
48
+ } else {
49
+ this.#hg.log4('find all size', records.length)
22
50
  list.push(...records)
23
51
  }
24
52
  })
25
- if(!callback){
53
+ if (!callback) {
26
54
  this.#hg.log4('find all len', list.length)
27
55
  }
28
56
  return list
29
57
  }
30
- async findOne(table,field,where){
31
- return await application.data.object(table).select(field || ['_id','_name']).where(where || {_id : application.operator.gte(0)}).findOne()
58
+ /**
59
+ * 查询单条记录
60
+ * @param table 表名
61
+ * @param field 需要返回的字段,默认 ['_id','_name']
62
+ * @param where 过滤条件
63
+ * @param useSystemAuth 是否使用系统权限;默认 false
64
+ * @returns 记录对象或 null
65
+ */
66
+ async findOne(table, fields, where, useSystemAuth = false) {
67
+ const object = application.data.object(table).select(fields || ['_id', '_name']).where(where || { _id: application.operator.gte(0) })
68
+ if (useSystemAuth) {
69
+ object.useSystemAuth()
70
+ }
71
+ return await object.findOne()
32
72
  }
33
- async findOneById(table,id,field){
34
- return await application.data.object(table).select(field || ['_id','_name']).where({_id: id}).findOne()
73
+ /**
74
+ * 根据 ID 查询单条记录
75
+ * @param table 表名
76
+ * @param id 记录 ID
77
+ * @param fields 需要返回的字段,默认 ['_id','_name']
78
+ * @param useSystemAuth 是否使用系统权限;默认 false
79
+ * @returns 记录对象或 null
80
+ */
81
+ async findOneById(table, id, fields, useSystemAuth = false) {
82
+ const object = application.data.object(table).select(fields || ['_id', '_name']).where({ _id: id })
83
+ if (useSystemAuth) {
84
+ object.useSystemAuth()
85
+ }
86
+ return await object.findOne()
35
87
  }
36
88
 
37
- async batchCreate(table,list){
38
- if(list.length){
39
- return await application.data.object(table).batchCreate(list)
89
+ /**
90
+ * 批量创建记录
91
+ * @param table 表名
92
+ * @param list 记录列表
93
+ * @param useSystemAuth 是否使用系统权限;默认 false
94
+ * @returns 创建的记录 ID 列表或 null
95
+ */
96
+ async batchCreate(table, list, useSystemAuth = false) {
97
+ if (list.length) {
98
+ const object = application.data.object(table)
99
+ if (useSystemAuth) {
100
+ object.useSystemAuth()
101
+ }
102
+ return await object.batchCreate(list)
40
103
  }
41
104
  return null
42
105
  }
43
- async create(table,data){
44
- return await application.data.object(table).create(data)
106
+ /**
107
+ * 创建单条记录
108
+ * @param table 表名
109
+ * @param data 记录数据
110
+ * @param useSystemAuth 是否使用系统权限;默认 false
111
+ * @returns 创建的记录 ID 或 null
112
+ */
113
+ async create(table, data, useSystemAuth = false) {
114
+ const object = application.data.object(table)
115
+ if (useSystemAuth) {
116
+ object.useSystemAuth()
117
+ }
118
+ return await object.create(data)
45
119
  }
46
120
 
47
- async batchUpdate(table,list){
48
- if(list.length){
49
- return application.data.object(table).batchUpdate(list)
121
+ /**
122
+ * 批量更新记录
123
+ * @param table 表名
124
+ * @param list 记录列表
125
+ * @param useSystemAuth 是否使用系统权限;默认 false
126
+ * @returns 更新的记录 ID 列表或 null
127
+ */
128
+ async batchUpdate(table, list, useSystemAuth = false) {
129
+ if (list.length) {
130
+ const object = application.data.object(table)
131
+ if (useSystemAuth) {
132
+ object.useSystemAuth()
133
+ }
134
+ return await object.batchUpdate(list)
50
135
  }
51
136
  return null
52
137
  }
53
- async update(table,data){
54
- return application.data.object(table).update(data)
138
+ /**
139
+ * 更新单条记录
140
+ * @param table 表名
141
+ * @param data 记录数据
142
+ * @param useSystemAuth 是否使用系统权限;默认 false
143
+ * @returns 更新的记录 ID 或 null
144
+ */
145
+ async update(table, data, useSystemAuth = false) {
146
+ const object = application.data.object(table)
147
+ if (useSystemAuth) {
148
+ object.useSystemAuth()
149
+ }
150
+ return await object.update(data)
55
151
  }
56
-
57
- async delete(table,_id){
58
- return application.data.object(table).delete(_id)
152
+ /**
153
+ * 删除单条记录
154
+ * @param table 表名
155
+ * @param _id 记录 ID
156
+ * @param useSystemAuth 是否使用系统权限;默认 false
157
+ * @returns 删除的记录 ID 或 null
158
+ */
159
+ async deleteOne(table, _id, useSystemAuth = false) {
160
+ const object = application.data.object(table)
161
+ if (useSystemAuth) {
162
+ object.useSystemAuth()
163
+ }
164
+ return await object.delete(_id)
59
165
  }
60
- async delete(table,_ids){
61
- if(_ids.length){
62
- return application.data.object(table).batchDelete(_ids)
166
+ /**
167
+ * 批量删除记录
168
+ * @param table 表名
169
+ * @param _ids 记录 ID 列表
170
+ * @param useSystemAuth 是否使用系统权限;默认 false
171
+ * @returns 删除的记录 ID 列表或 null
172
+ */
173
+ async deleteBatchByIds(table, _ids, useSystemAuth = false) {
174
+ if (_ids.length) {
175
+ const object = application.data.object(table)
176
+ if (useSystemAuth) {
177
+ object.useSystemAuth()
178
+ }
179
+ return await object.batchDelete(_ids)
63
180
  }
64
181
  return null
65
182
  }
66
-
183
+
67
184
 
68
185
  }
69
186
  module.exports = Object_
package/index.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ declare module 'HG' {
2
+ import { AxiosRequestConfig, AxiosResponse } from 'axios';
3
+
4
+ export interface HGLogger {
5
+ log: (...args: any[]) => void;
6
+ error: (...args: any[]) => void;
7
+ warn: (...args: any[]) => void;
8
+ }
9
+
10
+ export interface MultilingualData {
11
+ zh?: string;
12
+ en?: string;
13
+ }
14
+
15
+ export default class HG {
16
+ constructor(logger: HGLogger);
17
+
18
+ /* 属性 */
19
+ readonly object: any; // 对应 new Object_(this)
20
+ readonly utils: any; // 对应 new Utils(this)
21
+ private _time: number | null;
22
+
23
+ /* 公有方法 */
24
+ setLogger(logger: HGLogger): Promise<void>;
25
+
26
+ /* 计时相关 */
27
+ timeRun<T = any>(fn?: () => T | Promise<T>): Promise<T>;
28
+ newTime(): void;
29
+ printTime(): void;
30
+
31
+ /* 工具方法 */
32
+ sleep(time?: number): Promise<void>;
33
+
34
+ /* 网络请求 */
35
+ request<T = any>(config: AxiosRequestConfig): Promise<T>;
36
+ axios<T = any>(config: AxiosRequestConfig): Promise<AxiosResponse<T>>;
37
+
38
+ /* 多语言 */
39
+ toMultilingualByOpenPlatform(
40
+ zh: string | any[],
41
+ en?: string
42
+ ): application.constants.type.Multilingual;
43
+
44
+ toTextByMultilingual(
45
+ textArr: Array<{ language_code: string; text: string }>
46
+ ): string;
47
+
48
+ /* JSON 取值 */
49
+ toValue<T = any>(
50
+ obj: any,
51
+ path: string,
52
+ defaultValue?: T
53
+ ): T | undefined;
54
+
55
+ /* 数组辅助 */
56
+ listFind<T = any>(
57
+ list: T[],
58
+ key: keyof T,
59
+ target: any,
60
+ defValue?: T
61
+ ): T | undefined;
62
+
63
+ listMap<T = any, K extends keyof T = keyof T>(
64
+ list: T[],
65
+ key: K
66
+ ): Array<T[K]>;
67
+
68
+ /* 字符串转数字 */
69
+ textToFloat(textAmount: string | number | null | undefined, defValue?: number): number;
70
+
71
+ /* 日志 */
72
+ log(...arg: any[]): void;
73
+ log4(...arg: any[]): void;
74
+ log8(...arg: any[]): void;
75
+ logm(space: number, ...arg: any[]): void;
76
+ error(...arg: any[]): void;
77
+ warn(...arg: any[]): void;
78
+ }
79
+ }
package/index.js CHANGED
@@ -1,25 +1,14 @@
1
- const Users = require('./opensdk/users')
2
- const Document = require('./opensdk/document')
3
1
  const Utils = require('./utils/index')
4
- const Employee = require('./opensdk/employee')
5
- const Contract = require('./opensdk/contract')
6
2
  const Object_ = require('./apass/object_')
7
- class HG{
3
+ class HG {
8
4
  #logger
9
- #app_id
10
- #app_secret
11
- constructor(logger){
5
+ constructor(logger) {
12
6
  this.setLogger(logger)
13
- this.users = new Users(this)
14
- this.document = new Document(this)
15
- this.employee = new Employee(this)
16
- this.contract = new Contract(this)
17
7
  this.object = new Object_(this)
18
-
19
8
  this.utils = new Utils(this)
20
9
  this._time = null
21
10
  }
22
- setLogger(logger){
11
+ async setLogger(logger) {
23
12
  this.#logger = logger
24
13
  }
25
14
  /**
@@ -27,10 +16,10 @@ class HG{
27
16
  * @param {*} fn
28
17
  * @returns
29
18
  */
30
- async timeRun(fn){
19
+ async timeRun(fn) {
31
20
  this.newTime()
32
21
  let result = null
33
- if(fn){
22
+ if (fn) {
34
23
  result = await fn()
35
24
  }
36
25
  this.printTime()
@@ -41,16 +30,16 @@ class HG{
41
30
  * @param {*} time 毫秒
42
31
  * @returns
43
32
  */
44
- async sleep(time){
45
- return new Promise((r)=>setTimeout(()=>{ this.log4(`sleep ${(time || 1000)/1000}s`);r();},time || 1000))
33
+ async sleep(time) {
34
+ return new Promise((r) => setTimeout(() => { this.log4(`sleep ${(time || 1000) / 1000}s`); r(); }, time || 1000))
46
35
  }
47
36
 
48
37
  /**
49
38
  * 时间计划-记录
50
39
  */
51
- newTime(){
52
- if(this._time){
53
- this.log4('#time reset to before',(Date.now() - this._time)/1000, 's')
40
+ newTime() {
41
+ if (this._time) {
42
+ this.log4('#time reset to before', (Date.now() - this._time) / 1000, 's')
54
43
  }
55
44
  this.log4('#time reset')
56
45
  this._time = Date.now()
@@ -58,175 +47,107 @@ class HG{
58
47
  /**
59
48
  * 时间计划-打印耗时
60
49
  */
61
- printTime(){
62
- if(!this._time){
63
- return this.#logger.error('#time Error','The time has not been initialized ')
50
+ printTime() {
51
+ if (!this._time) {
52
+ return this.#logger.error('#time Error', 'The time has not been initialized ')
64
53
  }
65
- this.log4('#time',(Date.now() - this._time)/1000, 's')
54
+ this.log4('#time', (Date.now() - this._time) / 1000, 's')
66
55
  }
67
56
 
68
57
  /**
69
- * 设置app_id
70
- * @param {*} app_id
71
- * @param {*} app_secret
72
- */
73
- setAppId(app_id,app_secret){
74
- this.#app_id = app_id
75
- this.#app_secret = app_secret
76
- }
77
-
78
- /**
79
- * 开平token
58
+ * 统一网络请求(使用axios)
59
+ * @param {*} config
80
60
  * @returns
81
61
  */
82
- async getToken(){
83
- 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)
84
- return result.tenant_access_token
85
- }
86
-
87
- async requestGet(url, params, headers=true){
88
- return this.request([url, params], null, headers, 'GET')
89
- }
90
-
91
- /**
92
- * 统一网络请求
93
- * @param {*} url
94
- * @param {*} params
95
- * @param {*} data
96
- * @param {*} headers
97
- * @param {*} method
98
- * @returns
99
- */
100
- async request(url, data, headers = true, method = 'POST'){
101
- let newHeaders = { 'Content-Type': 'application/json; charset=utf-8' }
102
- if(typeof headers === 'boolean' && headers === true){
103
- newHeaders['Authorization'] = `Bearer ${ await this.getToken() }`
104
- }else{
105
- newHeaders = { ...newHeaders,...(headers || {}) }
106
- }
107
- this.log4('req =',url,data,newHeaders)
108
- let _url = url
109
- let params = null
110
- if(Array.isArray(url)){
111
- _url = url[0]
112
- params = url[1]
113
- }
114
- return new Promise((r,s)=>{
62
+ async request(config) {
63
+ this.log4('req =', config)
64
+ return new Promise((r, s) => {
115
65
  const now = Date.now()
116
- axios({ method, params, url: _url, data, headers: newHeaders}).then(response=>{
117
- this.log8('resp =',(Date.now() - now) / 1000, 's',response.status, response.statusText,response.data)
66
+ axios(config).then(response => {
67
+ this.log8('resp =', (Date.now() - now) / 1000, 's', response.status, response.statusText, response.data)
118
68
  r(response.data)
119
- }).catch(e=>{
120
- console.log(e)
121
- this.#logger.error('resp =',(Date.now() - now) / 1000, 's',e.response.data)
122
- s(e.response.data)
69
+ }).catch(err => {
70
+ this.#logger.error('resp =', (Date.now() - now) / 1000, 's', err.response.data)
71
+ s(err.response.data)
123
72
  })
124
73
  })
125
74
  }
126
75
  /**
127
- * 分页返回开放平台数据
128
- * @param {*} url
129
- * @param {*} params
130
- * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
131
- * @returns 如果callback为传递则一次性返回所有的数据
132
- */
133
- async paginatedSearchGet(url,params,callback){
134
- return this.paginatedSearch(url, params, null, callback, 'GET')
135
- }
136
- /**
137
- * 分页返回开放平台数据
138
- * @param {*} url
139
- * @param {*} params
140
- * @param {*} data
141
- * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
142
- * @returns 如果callback为传递则一次性返回所有的数据
76
+ * 直接调用axios
77
+ * @param {*} config
78
+ * @returns
143
79
  */
144
- async paginatedSearch(url,params,data,callback,method='POST'){
145
- let list = []
146
- let page_token = null
147
- let has_more = false
148
- do {
149
- const result = await this.request([url, {...(params || {page_size: 100}), page_token}],data,true,method)
150
- page_token = result.data.page_token
151
- has_more = result.data.has_more
152
- if(callback){
153
- await callback(result.data.hasOwnProperty('items') ? result.data.items || [] : result.data)
154
- }else{
155
- if(result.data.hasOwnProperty('items')){
156
- list.push(...(result.data.items || []))
157
- }else{
158
- list.push(result.data)
159
- }
160
- }
161
- } while (has_more);
162
- return list
80
+ axios(config) {
81
+ return axios(config)
163
82
  }
164
-
165
83
  /**
166
- * 生成多语言对象
84
+ * 生成多语言对象(将开放平台返回的多语言对象转换为application.constants.type.Multilingual)
167
85
  * @param {*} zh
168
86
  * @param {*} en
169
87
  * @returns
170
88
  */
171
- toMultilingual(zh,en){
172
- if(Array.isArray(zh)){
173
- //开放平台一般返回内容
174
- if(zh[0].hasOwnProperty('lang')){
175
- const _zh = this.toSafeValue(zh.find(it=>it.lang == 'zh-CN'),'value')
176
- const _en = this.toSafeValue(zh.find(it=>it.lang == 'en-US'),'value')
89
+ toMultilingualByOpenPlatform(zh, en) {
90
+ if (Array.isArray(zh)) {
91
+ if (zh[0].hasOwnProperty('lang')) {
92
+ const _zh = this.toValue(zh.find(it => it.lang == 'zh-CN'), 'value')
93
+ const _en = this.toValue(zh.find(it => it.lang == 'en-US'), 'value')
177
94
  return new application.constants.type.Multilingual({ zh: _zh || _en, en: _en || _zh })
178
95
  }
179
- if(zh[0].hasOwnProperty('locale')){
180
- const _zh = this.toSafeValue(zh.find(it=>it.locale == 'zh_CN'),'value')
181
- const _en = this.toSafeValue(zh.find(it=>it.locale == 'en_US'),'value')
96
+ if (zh[0].hasOwnProperty('locale')) {
97
+ const _zh = this.toValue(zh.find(it => it.locale == 'zh_CN' || it.locale == 'zh-CN'), 'value')
98
+ const _en = this.toValue(zh.find(it => it.locale == 'en_US' || it.locale == 'en-US'), 'value')
182
99
  return new application.constants.type.Multilingual({ zh: _zh || _en, en: _en || _zh })
183
100
  }
184
101
  }
185
102
  return new application.constants.type.Multilingual({ zh: zh || en, en: en || zh })
186
103
  }
187
-
188
104
  /**
189
- * 安全的取值
105
+ * 从多语言对象中获取中文
106
+ * @param {*} textArr
107
+ * @returns
108
+ */
109
+ toTextByMultilingual(textArr) {
110
+ if (!textArr || !textArr.length) return '--'
111
+ return textArr.find(it => it.language_code == '2052').text
112
+ }
113
+ /**
114
+ * 从JSON中根据路径获取值
190
115
  * @param {*} obj
191
- * @param {*} key
192
- * @param {*} defValue
116
+ * @param {*} path
117
+ * @param {*} defaultValue
193
118
  * @returns
194
119
  */
195
- toSafeValue(obj,key,defValue){
196
- const _obj = obj || {}
197
- if(!_obj){
198
- return defValue
199
- }
200
- if(!_obj.hasOwnProperty(key)){
201
- return defValue
202
- }
203
- return _obj[key] || defValue
120
+ toValue(obj, path, defaultValue = undefined) {
121
+ return path.split('.').reduce((acc, key) => acc?.[key], obj) ?? defaultValue;
204
122
  }
205
-
206
- listFind(list,key,target,defValue){
207
- return list.find(it=>it[ key ] == target) || defValue
123
+ listFind(list, key, target, defValue) {
124
+ return list.find(it => it[key] == target) || defValue
208
125
  }
209
- listMap(list,key){
210
- return list.map(it=>it[ key ])
126
+ listMap(list, key) {
127
+ return list.map(it => it[key])
211
128
  }
212
-
213
- textToFloat(textAmount,defValue = 0) {
129
+ textToFloat(textAmount, defValue = 0) {
214
130
  return parseFloat((textAmount || '').replace(/,/g, '') || defValue);
215
131
  }
216
132
 
217
- log(...arg){
133
+ log(...arg) {
218
134
  this.#logger.log(...arg)
219
135
  }
220
- log4(...arg){
221
- this.logm(4,...arg)
136
+ log4(...arg) {
137
+ this.logm(4, ...arg)
222
138
  }
223
- log8(...arg){
224
- this.logm(8,...arg)
139
+ log8(...arg) {
140
+ this.logm(8, ...arg)
225
141
  }
226
- logm(space,...arg){
142
+ logm(space, ...arg) {
227
143
  const result = ''.padEnd(space, "-");
228
- this.#logger.log(result,...arg)
144
+ this.#logger.log(result, ...arg)
145
+ }
146
+ error(...arg) {
147
+ this.#logger.error(...arg)
148
+ }
149
+ warn(...arg) {
150
+ this.#logger.warn(...arg)
229
151
  }
230
-
231
152
  }
232
153
  module.exports = HG
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "apass-opensdk-hugong",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "飞书Apass低代码平台-飞书开放平台-相关的接口整合和常用的方法整合",
5
5
  "main": "index.js",
6
+ "types": "index.d.ts",
6
7
  "scripts": {
7
8
  "test": "echo \"Error: no test specified\" && exit 1"
8
9
  },
package/readme.md CHANGED
@@ -1,56 +1,54 @@
1
1
  # apass-opensdk-hugong
2
2
  ## 简介
3
- apass-opensdk-hugong 是一个基于apass-opensdk的封装,提供了一些常用的功能
3
+ apass-opensdk-hugong 是一个Nodejs的SDK,提供了一些常用的功能
4
4
  - 什么人可以使用这个SDK
5
- - 从事飞书低代码平台(APASS)开发人员.
5
+ - 从事飞书低代码平台(APASS)开发人员.传统Nodejs开发人员.
6
6
 
7
7
  ## 安装
8
8
 
9
9
  ```
10
10
  在飞书低代码平台(云函数)依赖管理-右侧-搜索: apass-opensdk-hugong
11
-
12
- 最近有同学私聊我说Apass无法安装1.0.0以上的包,解决思路: 先安装1.0.0版本,然后打开yarn.lock文件
13
- ====== 找到这一行 =====
14
- apass-opensdk-hugong@1.0.0:
15
- version "1.0.0"
16
- resolved "https://registry.npmmirror.com/apass-opensdk-hugong/-/apass-opensdk-hugong-1.0.0.tgz#ef2d0a19e793358784cb764de4b885fd86befd66"
17
- integrity sha512-Q8Gpo9v8a/2G43y/Lh2POyDEOcealFuUlGdqGSA9wyfjET4+LWs/PnzK9EB1YZCjQotW7cGO/9a0MiQ6Sgw1LA==
18
- ====== 找到这一行 =====
19
-
20
- 将版本改为最新的版本号后,然后保存,重写部署即可使用NPM源最新的版本
21
- 修改后的yarn.lock文件如下, 一共三处地方:
22
- apass-opensdk-hugong@1.0.3:
23
- version "1.0.3"
24
- resolved "https://registry.npmmirror.com/apass-opensdk-hugong/-/apass-opensdk-hugong-1.0.3.tgz#ef2d0a19e793358784cb764de4b885fd86befd66"
25
- integrity sha512-Q8Gpo9v8a/2G43y/Lh2POyDEOcealFuUlGdqGSA9wyfjET4+LWs/PnzK9EB1YZCjQotW7cGO/9a0MiQ6Sgw1LA==
26
11
  ```
27
12
 
28
13
  ## 如何使用
29
14
  ```
30
15
  const Hugong = require('apass-opensdk-hugong');
31
- 初始化
16
+ 初始化(主函数内),函数外不需要入参logger
32
17
  const hg = new Hugong(logger)
18
+
19
+ 也可以单独初始化logger模块
20
+ hg.setLogger(logger)
33
21
  ```
34
22
  ## 常用
35
23
  ```
36
- 显示运行时间
24
+ 记录时间
37
25
  hg.newTime()
26
+ 打印运行时间
38
27
  hg.printTime()
39
28
 
29
+ 安全的取值
30
+ hg.toValue({....},'a.b.c','default value')
31
+
40
32
  线程睡眠(毫秒)
41
33
  await hg.sleep(2000)
42
34
 
43
- 支持将数组分割成指定长度分段数组
44
- 第一种用法,一次性返还分割后的数组
45
- const list = hg.utils.splitArray([], 50) 输出 [ [50],[50] ]
46
-
47
- 第二种用法,每次输出50条 处理完成后继续下次执行
48
- await hg.utils.splitArray([], 10, async (items)=>{
49
- // do something
50
- })
35
+ 数组操作
36
+ 1)生成指定范围的数组
37
+ const rangeValue = hg.utils.range(5,50, 3)
38
+ out=[ 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50 ]
39
+ 2)数组分块
40
+ const chunkValue = hg.utils.chunkAll(rangeValue, 5)
41
+ out=[ [ 5, 8, 11, 14, 17 ], [ 20, 23, 26, 29, 32 ], [ 35, 38, 41, 44, 47 ], [ 50 ] ]
42
+ 数组分块输出1
43
+ hg.utils.splitArray([....], 5) 输出 [ [50],[50] ]
44
+ out=[ [ 5, 8, 11, 14, 17 ], [ 20, 23, 26, 29, 32 ], [ 35, 38, 41, 44, 47 ], [ 50 ] ]
45
+ 数组分块输出2,每次输出50条 处理完成后继续下次执行
46
+ await hg.utils.splitArray([...], 10, async (items)=>{ // do something })
47
+ 移除重复项
48
+ hg.utils.unique([1,2,3,1,2,3]) // [1,2,3]
51
49
 
52
50
  ```
53
- ## 文件上传/下载
51
+ ## Apass相关,文件上传/下载
54
52
 
55
53
  ```
56
54
  1)从网络下载文件后上传到飞书租户空间,返回上传后的文件信息
@@ -61,18 +59,25 @@ await hg.utils.file.downloadFileToUpload(url,{ Authorization: `...`})
61
59
  saveDataToEnv(data,path)
62
60
 
63
61
  1)从飞书租户空间下载文件到本地环境中
64
- file_info={ id, mime_type, name, ...}
65
- file_path=存储地址可选,不填写则默认当前时间戳
62
+ file_info={ id, mime_type, ...}
63
+ file_path=存储地址可选,不填写则默认当前时间戳
66
64
  await hg.utils.file.downloadFileToTmp(fileInfo,file_path)
65
+ 如果是token文件
66
+ file_info={ token, mime_type, ...}
67
+ await hg.utils.file.downloadFileByToeknToTmp(file_info,file_path)
67
68
 
68
69
  2)解析csv文件,file_path必须是本地环境的文件路径 /tep/aaa.csv 可以使用上面的方法downloadFileToTmp下载文件到本地环境中
69
70
  await hg.utils.file.csvRead(file_path,callback)
70
71
  示例1 读取完成后返回数组
71
72
  const list = await hg.utils.file.csvRead(file_path)
72
- 示例2 读取完成后回调
73
+ 示例2 读取完成后回调, 超过5000条建议使用此方法防止内存溢出
73
74
  await hg.utils.file.csvRead(file_path,async (row)=>{
74
75
  // do something
75
76
  })
77
+
78
+ 3)解析excel文件,file_path必须是本地环境的文件路径 /tep/aaa.xlsx 可以使用上面的方法downloadFileToTmp下载文件到本地环境中
79
+ const list = hg.utils.file.xlsxReaderAll(file_path)
80
+ list是excel所有的内容,建议小文件使用(10M以下),如果是大文件10M以上转换成csv使用上面的方法,亲自测试10万条csv读取正常
76
81
  ```
77
82
 
78
83
  ## 小工具/多语言
@@ -80,75 +85,12 @@ await hg.utils.file.csvRead(file_path,async (row)=>{
80
85
  ```
81
86
  对象数据新增多语言对象
82
87
 
83
- 生成多语言对象
84
- hg.toMultilingual([{ lang: 'en-US', value: 'Regular' },{ lang: 'zh-CN', value: '正式' }]) 常用于开放平台返回的多语言数据转换
85
- hg.toMultilingual(zh,en)
86
-
87
- 安全的取值
88
- hg.toSafeValue(obj={},key,defValue)
88
+ 生成多语言对象(将开放平台返回的多语言对象转换为application.constants.type.Multilingual)
89
+ hg.toMultilingualByOpenPlatform([{ lang: 'en-US', value: 'Regular' },{ lang: 'zh-CN', value: '正式' }])
90
+ hg.toMultilingualByOpenPlatform(zh,en)
89
91
 
90
92
  ```
91
93
 
92
- ## 飞书人事
93
-
94
- 搜索员工信息
95
-
96
- ```
97
- 设置appid和appsecret
98
- await hg.setAppId('cli_000000000','0000000000000')
99
-
100
- /**
101
- * 搜索员工信息
102
- * @param {*} params
103
- * @param {*} data
104
- * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
105
- * @returns 如果callback为传递则一次性返回所有的数据
106
- */
107
- await hg.employee.search(params,data,callback)
108
-
109
- // 示例[具体参数请参考开放平台定义](https://open.feishu.cn/document/server-docs/corehr-v1/employee/search)
110
- await hg.employee.search({ page_size:100,user_id_type:'user_id',},{ /* 要查询的字段 */}, async (items)=>{
111
- // do something 假设服务端有300条数据,每次返回100条,会调用3次, 如果希望一次性返回所有数据,callback传null即可
112
- })
113
- const list = await hg.employee.search(params,data) //这将一次性返回所有数据
114
- ```
115
- ## 开放平台分页获取所有数据
116
-
117
- 所有的分页接口都可以使用
118
-
119
- ```
120
- 设置appid和appsecret
121
- await hg.setAppId('cli_000000000','0000000000000')
122
-
123
- /**
124
- * GET类型接口分页返回开放平台数据
125
- * @param {*} url
126
- * @param {*} params
127
- * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
128
- * @returns callback为null,则一次性返回所有的数据
129
- */
130
- hg.paginatedSearchGet(url,params,callback)
131
-
132
- /**
133
- * POST接口分页返回开放平台数据
134
- * @param {*} url
135
- * @param {*} params
136
- * @param {*} data
137
- * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
138
- * @returns callback为null,则一次性返回所有的数据
139
- */
140
- await hg.paginatedSearch(url,params,data,callback)
141
-
142
- 示例1
143
- const list = await hg.paginatedSearchGet(url, params, data)
144
- 示例2
145
- await hg.paginatedSearchGet(url, params, async (items)=>{
146
- // do something 假设服务端有300条数据,每次返回100条,会调用3次, 如果希望一次性返回所有数据,callback传null即可
147
- })
148
- ```
149
-
150
-
151
-
152
94
  ## 交流学习
153
95
 
154
96
  从事飞书低代码平台(APASS)开发人员3年,欢迎交流学习
@@ -0,0 +1,35 @@
1
+ // Date_.d.ts
2
+ export = Date_;
3
+
4
+ declare class Date_ {
5
+ constructor(hg: any);
6
+
7
+ /**
8
+ * 把日期字符串解析成时间戳(毫秒)
9
+ */
10
+ dateStringToTimestamp(dateString: string): number;
11
+
12
+ /**
13
+ * 返回 moment-timezone 实例(已默认 Asia/Shanghai)
14
+ */
15
+ moment(date?: string | number | Date): import('moment-timezone').Moment;
16
+
17
+ /**
18
+ * 当前时间按指定格式输出(默认 YYYY-MM-DD HH:mm:ss)
19
+ */
20
+ nowFormat(format?: string): string;
21
+
22
+ /**
23
+ * 把起止日期按指定月份跨度拆分成若干段
24
+ */
25
+ splitDateRange(
26
+ startDate: string,
27
+ endDate: string,
28
+ splitMonths: number
29
+ ): Array<{
30
+ begin: string; // yyyy-mm-dd
31
+ end: string; // yyyy-mm-dd
32
+ len: number; // 实际月份数
33
+ days: number; // 实际天数
34
+ }>;
35
+ }
package/utils/date_.js CHANGED
@@ -4,10 +4,17 @@ class Date_{
4
4
  constructor(hg){
5
5
  this.#hg = hg
6
6
  }
7
- moment(){
7
+
8
+ dateStringToTimestamp(dateString){
9
+ const timestamp = Date.parse(dateString);
10
+ //this.#hg.log4(`dateString=${dateString}, timestamp=${timestamp}`)
11
+ return timestamp
12
+ }
13
+
14
+ moment(date){
8
15
  const moment = require('moment-timezone');
9
16
  moment.tz.setDefault("Asia/Shanghai");
10
- return moment()
17
+ return moment(date || Date.now())
11
18
  }
12
19
  nowFormat(format) {
13
20
  const moment = require('moment-timezone');
@@ -0,0 +1,77 @@
1
+ // File_.d.ts
2
+ export = File_;
3
+
4
+ declare class File_ {
5
+ constructor(hg: any);
6
+
7
+ /** 生成当前时间文件夹名:yyyy-MM-dd_HH-mm-ss */
8
+ getCurrentTimeFolderName(): string;
9
+
10
+ /**
11
+ * 网络下载文件并上传到租户空间
12
+ * @param url 网络文件地址
13
+ * @param header 可选请求头
14
+ * @returns 上传后的文件信息
15
+ */
16
+ downloadFileToUpload(
17
+ url: string,
18
+ header?: Record<string, string>
19
+ ): Promise<FileInfo>;
20
+
21
+ /**
22
+ * 下载租户空间的文件到环境 tmp 目录
23
+ * @param file_info 文件元数据
24
+ * @param file_path 本地存储路径(可选)
25
+ * @returns 本地文件路径
26
+ */
27
+ downloadFileToTmp(
28
+ file_info: FileInfo,
29
+ file_path?: string
30
+ ): Promise<string>;
31
+
32
+ /**
33
+ * 使用 token 下载文件到环境 tmp 目录
34
+ * @param file_info 必须包含 token 与 mime_type
35
+ * @param file_path 本地存储路径(可选)
36
+ * @returns 本地文件路径
37
+ */
38
+ downloadFileByToeknToTmp(
39
+ file_info: Pick<FileInfo, 'token' | 'mime_type'>,
40
+ file_path?: string
41
+ ): Promise<string>;
42
+
43
+ /**
44
+ * 将数据追加写入文件
45
+ * @param data 写入内容
46
+ * @param fileName 文件名(可选)
47
+ */
48
+ saveDataToEnv(data: string, fileName?: string): void;
49
+
50
+ /**
51
+ * 读取 CSV 文件(依赖 csv-parser)
52
+ * @param path 文件路径
53
+ * @param callback 每行回调,返回 void 时一次性返回所有行
54
+ * @returns 无回调时返回全部行
55
+ */
56
+ csvRead<T = Record<string, any>>(
57
+ path: string,
58
+ callback: (row: T, index: number) => void
59
+ ): Promise<void>;
60
+ csvRead<T = Record<string, any>>(path: string): Promise<T[]>;
61
+
62
+ /**
63
+ * 读取 Excel 文件(依赖 xlsx@0.18.5)
64
+ * @param filePath 文件路径
65
+ * @returns 工作表第一页的全部数据
66
+ */
67
+ xlsxReaderAll(filePath: string): any[];
68
+ }
69
+
70
+ /* ── 依赖类型 ─────────────────────────────── */
71
+ interface FileInfo {
72
+ id?: string;
73
+ token?: string;
74
+ mime_type: string;
75
+ name?: string;
76
+ [key: string]: any;
77
+ }
package/utils/file_.js CHANGED
@@ -41,6 +41,13 @@ class File_{
41
41
  this.#hg.log4(`download success, path=` + _file_path)
42
42
  return _file_path
43
43
  }
44
+ async downloadFileByToeknToTmp(file_info, file_path){
45
+ this.#hg.log4(`download input=${ JSON.stringify(file_info)}`)
46
+ const _file_path = file_path || `/tmp/${Date.now()}.${ file_info.mime_type }`
47
+ await application.resources.file.download(file_info.token, _file_path);
48
+ this.#hg.log4(`download success, path=` + _file_path)
49
+ return _file_path
50
+ }
44
51
  /**
45
52
  * 写入文件
46
53
  * @param {*} data 写入的内容
@@ -50,7 +57,7 @@ class File_{
50
57
  fs.writeFileSync(fileName || `${ Date.now() }.txt`,data, { flag: 'a' })
51
58
  }
52
59
  /**
53
- * 读取Excel文件(需要安装依赖:csv-parser)
60
+ * 读取csv文件(需要安装依赖:csv-parser)
54
61
  * @param {*} path
55
62
  * @param {*} callback(row) 每一行的回调
56
63
  * @returns callback为null时,返回全部读取的结果list
@@ -59,10 +66,11 @@ class File_{
59
66
  const csv = require('csv-parser');
60
67
  return await new Promise((resolve, reject) => {
61
68
  const list = []
69
+ let index = 0
62
70
  fs.createReadStream(path).pipe(csv())
63
71
  .on('data', (row) => {
64
72
  if(callback){
65
- callback(row)
73
+ callback(row,index++)
66
74
  }else{
67
75
  list.push(row)
68
76
  }
@@ -76,14 +84,26 @@ class File_{
76
84
  })
77
85
  }
78
86
 
79
- async excelReader(path,callback){
87
+ /**
88
+ * 读取Excel文件(需要安装依赖:xlsx@0.18.5)
89
+ * @param {*} filePath
90
+ * @returns 返回文件内容
91
+ */
92
+ xlsxReaderAll(filePath){
80
93
  const XLSX = require('xlsx');
81
- const stream = fs.createReadStream(path.join(__dirname, 'example.xlsx'));
82
- const workbook = XLSX.read(stream, { type: 'buffer' });
83
- const sheetName = workbook.SheetNames[0];
84
- const worksheet = workbook.Sheets[sheetName];
85
- const data = XLSX.utils.sheet_to_json(worksheet);
86
- console.log(data);
94
+ let data = []
95
+ try {
96
+ const buffer = fs.readFileSync(filePath)
97
+ const workbook = XLSX.read(buffer, { type: 'buffer' });
98
+ const sheetName = workbook.SheetNames[0];
99
+ this.#hg.log4('Sheet Name:', sheetName);
100
+ const worksheet = workbook.Sheets[sheetName];
101
+ data = XLSX.utils.sheet_to_json(worksheet);
102
+ this.#hg.log4('Data:', data);
103
+ } catch (error) {
104
+ this.#hg.error('xlsxReaderAll - Error parsing Excel file:', error);
105
+ }
106
+ return data
87
107
  }
88
108
  }
89
109
  module.exports = File_
@@ -0,0 +1,44 @@
1
+
2
+ // Utils.d.ts
3
+ export = Utils;
4
+
5
+ declare class Utils {
6
+ constructor(hg: any);
7
+
8
+ /** 网络/文件/日期 子模块 */
9
+ readonly url: import('./url');
10
+ readonly file: import('./file_');
11
+ readonly date: import('./date_');
12
+
13
+ /**
14
+ * 数组分块(支持同步/异步回调)
15
+ * @param list 原始数组
16
+ * @param chunkSize 每块长度
17
+ * @param callback 每块回调;如提供,则整体返回 void
18
+ * @returns 无回调时返回分块后的二维数组
19
+ */
20
+ splitArray<T = any>(
21
+ list: T[],
22
+ chunkSize: number,
23
+ callback?: (batch: T[]) => Promise<void> | void
24
+ ): Promise<T[][] | void>;
25
+
26
+ /** 计算字符串 MD5 */
27
+ toMD5(data: string): string;
28
+
29
+ /** 按区域与币种格式化金额 */
30
+ formatCurrency(
31
+ amount: number,
32
+ locale?: string,
33
+ currency?: string
34
+ ): string;
35
+
36
+ /** 将数组按固定大小分块(同步) */
37
+ chunkAll<T = any>(arr: T[], size: number): T[][];
38
+
39
+ /** 生成指定步长的数值范围数组 */
40
+ range(start: number, end: number, step?: number): number[];
41
+
42
+ /** 数组去重 */
43
+ unique<T = any>(arr: T[]): T[];
44
+ }
package/utils/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  const Url = require('./url')
2
2
  const File_ = require('./file_')
3
3
  const Date_ = require('./date_')
4
- class Utils{
4
+ class Utils {
5
5
  #hg = null
6
- constructor(hg){
6
+ constructor(hg) {
7
7
  this.#hg = hg
8
8
 
9
9
  this.url = new Url(hg)
@@ -18,13 +18,13 @@ class Utils{
18
18
  * @param {*} callback(item) 分割后回调(不传递则方法返回切割长度后的数组)
19
19
  * @returns
20
20
  */
21
- async splitArray(list, chunkSize, callback) {
21
+ async splitArray(list, chunkSize, callback) {
22
22
  const result = [];
23
23
  this.#hg.log4('splitArray len ', list.length)
24
24
  for (let i = 0; i < list.length; i += chunkSize) {
25
25
  const batch = list.slice(i, i + chunkSize)
26
- this.#hg.log8('splitArray item ',i, i + chunkSize)
27
- if(callback){
26
+ this.#hg.log8('splitArray item ', i, i + chunkSize)
27
+ if (callback) {
28
28
  await callback(batch)
29
29
  continue
30
30
  }
@@ -33,7 +33,7 @@ class Utils{
33
33
  return result;
34
34
  }
35
35
 
36
- toMD5(data){
36
+ toMD5(data) {
37
37
  const crypto = require('crypto');
38
38
  const hash = crypto.createHash('md5');
39
39
  hash.update(data);
@@ -42,5 +42,48 @@ class Utils{
42
42
  return md5Hash
43
43
  }
44
44
 
45
+
46
+ /**
47
+ * 格式化货币
48
+ * @param {*} amount
49
+ * @param {*} locale
50
+ * @param {*} currency
51
+ * @returns
52
+ */
53
+ formatCurrency(amount, locale = 'en-US', currency = 'USD') {
54
+ return new Intl.NumberFormat(locale, { style: 'currency', currency, }).format(amount);
55
+ }
56
+
57
+ /**
58
+ * 分块数组
59
+ * @param {*} arr
60
+ * @param {*} size
61
+ * @returns
62
+ */
63
+ chunkAll(arr, size) {
64
+ return Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size));
65
+ }
66
+
67
+
68
+ /**
69
+ * 范围生成器
70
+ * @param {*} start
71
+ * @param {*} end
72
+ * @param {*} step
73
+ * @returns
74
+ */
75
+ range(start, end, step = 1) {
76
+ return Array.from({ length: (end - start) / step + 1 }, (_, i) => start + i * step);
77
+ }
78
+
79
+ /**
80
+ * 移除重复项
81
+ * @param {*} arr
82
+ * @returns
83
+ */
84
+ unique(arr) {
85
+ return [...new Set(arr)];
86
+ }
87
+
45
88
  }
46
89
  module.exports = Utils
@@ -1,17 +0,0 @@
1
- class Contract{
2
- #hg = null
3
- constructor(hg){
4
- this.#hg = hg
5
- }
6
-
7
- /**
8
- * 通过手机号或邮箱获取用户 ID
9
- * @param {*} user_id_type user_id、open_id、union_id
10
- * @returns
11
- */
12
- async batch_get_id(data,user_id_type){
13
- 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)
14
- }
15
-
16
- }
17
- module.exports = Contract
@@ -1,46 +0,0 @@
1
- class Document{
2
- #hg = null
3
- constructor(hg){
4
- this.#hg = hg
5
- }
6
- /**
7
- * 增加协作者权限 https://open.feishu.cn/document/server-docs/docs/permission/permission-member/create
8
- * @param {*} app_token app_token 多维表格 App 的唯一标识
9
- * @param {*} type 文件类型 bitable:多维表格
10
- * @param {*} data {
11
- "member_type": "openchat",
12
- "member_id": "oc_b962e8debdc37712a1d60bb97087a8e8",
13
- "perm": "edit",
14
- "perm_type": "container",
15
- "type": "chat"
16
- }
17
- */
18
- async permissions(app_token,type,data){
19
- if(!type){
20
- throw 'type is not empty'
21
- }
22
- return await this.#hg.request(`https://open.feishu.cn/open-apis/drive/v1/permissions/${app_token}/members?type=${type}&need_notification=false`,data,true)
23
- }
24
- /**
25
- * 复制多维表格 https://open.feishu.cn/document/server-docs/docs/bitable-v1/app/copy
26
- * @param {*} app_token 要复制的多维表格 App 的唯一标识
27
- * @param {*} name 多维表格 App 名称。最长为 255 个字符
28
- * @param {*} folder_token 文件夹
29
- * @returns
30
- */
31
- async copy(app_token,name,folder_token,without_content,time_zone){
32
- 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)
33
- }
34
- /**
35
- * 创建多维表格 https://open.feishu.cn/document/server-docs/docs/bitable-v1/app/create
36
- * @param {*} name 多维表格 App 名称
37
- * @param {*} folder_token 多维表格 App 归属文件夹
38
- * @param {*} time_zone
39
- * @returns
40
- */
41
- async create(name, folder_token, time_zone){
42
- return await this.#hg.request('https://open.feishu.cn/open-apis/bitable/v1/apps',{ name, folder_token, time_zone: time_zone || 'Asia/Shanghai' },true)
43
- }
44
-
45
- }
46
- module.exports = Document
@@ -1,18 +0,0 @@
1
- class Employee{
2
- #hg = null
3
- constructor(hg){
4
- this.#hg = hg
5
- }
6
-
7
- /**
8
- * 搜索员工信息
9
- * @param {*} params
10
- * @param {*} data
11
- * @param {*} callback(items) 结果回调(根据总数可能多次调用)
12
- */
13
- async search(params,data,callback){
14
- return await this.#hg.paginatedSearch(`https://open.feishu.cn/open-apis/corehr/v2/employees/search`,params,data,callback)
15
- }
16
-
17
- }
18
- module.exports = Employee
package/opensdk/users.js DELETED
@@ -1,17 +0,0 @@
1
- class Users{
2
- #hg = null
3
- constructor(hg){
4
- this.#hg = hg
5
- }
6
-
7
- /**
8
- * 通过手机号或邮箱获取用户 ID
9
- * @param {*} user_id_type user_id、open_id、union_id
10
- * @returns
11
- */
12
- async batch_get_id(data,user_id_type){
13
- 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)
14
- }
15
-
16
- }
17
- module.exports = Users