sdk/dingding-sdk/main.py

225 lines
7.5 KiB
Python

from flask import Flask, request, jsonify
from dingding_attendance import DingTalkDocsFetcher # 你保存代码的文件名
from dingding_calendars import DingTalkHelper
import concurrent.futures
from dingding_wiki_team_file import get_access_token,get_unionid,create_wiki_client,list_workspaces,list_all_nodes,get_admin_userid,get_workspaces_details
from dingding_wiki_file import get_user_root_node_id,get_department_list,get_department_users
app = Flask(__name__)
def obj_to_dict(obj):
if isinstance(obj, list):
return [obj_to_dict(i) for i in obj]
if isinstance(obj, dict):
return {k: obj_to_dict(v) for k,v in obj.items()}
if hasattr(obj, 'to_map'):
return obj.to_map()
if hasattr(obj, '__dict__'):
return {k: obj_to_dict(v) for k, v in obj.__dict__.items() if not k.startswith('_')}
return obj
def to_dict(ws):
return {
"name": getattr(ws, "name", ""),
"workspace_id": getattr(ws, "workspace_id", ""),
"type": getattr(ws, "type", ""),
"url": getattr(ws, "url", ""),
}
#获取钉钉打卡信息
@app.route('/dingding_attendance', methods=['POST'])
def attendance():
data = request.json
app_key = data.get('app_key')
app_secret = data.get('app_secret')
date_from = data.get('date_from')
date_to = data.get('date_to')
if not all([app_key, app_secret, date_from, date_to]):
return jsonify({"error": "app_key, app_secret, date_from, date_to 均为必填参数"}), 400
token = DingTalkDocsFetcher.get_access_token(app_key, app_secret)
if not token:
return jsonify({"error": "获取AccessToken失败"}), 500
departments = DingTalkDocsFetcher.get_all_departments(token)
if not departments:
return jsonify({"error": "获取部门失败"}), 500
user_ids = list(DingTalkDocsFetcher.get_all_user_ids(token, departments))
if not user_ids:
return jsonify({"error": "没有获取到用户ID"}), 500
records = DingTalkDocsFetcher.get_attendance_records(token, user_ids, date_from, date_to)
if records is None:
return jsonify({"error": "获取打卡记录失败"}), 500
user_cache = {}
def fetch_user_detail(uid):
if uid in user_cache:
return uid, user_cache[uid]
detail = DingTalkDocsFetcher.get_user_detail(token, uid)
user_cache[uid] = detail
return uid, detail
user_ids_in_records = list({r.get("userId") for r in records if r.get("userId")})
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = [executor.submit(fetch_user_detail, uid) for uid in user_ids_in_records]
for future in concurrent.futures.as_completed(futures):
uid, detail = future.result()
user_cache[uid] = detail
for r in records:
detail = user_cache.get(r.get("userId"))
r["user_name"] = detail.get("name", "") if detail else ""
r["user_unionid"] = detail.get("unionid", "") if detail else ""
return jsonify({
"departments_count": len(departments),
"users_count": len(user_ids),
"attendance_records_count": len(records),
"attendance_records": records
})
#获取钉钉日历日程信息
@app.route('/dingding_calendar', methods=['POST'])
def user_calendar():
data = request.json
app_key = data.get("app_key")
app_secret = data.get("app_secret")
if not all([app_key, app_secret]):
return jsonify({"error": "app_key 和 app_secret 均为必填参数"}), 400
token = DingTalkHelper.get_access_token(app_key, app_secret)
if not token:
return jsonify({"error": "获取AccessToken失败"}), 500
departments = DingTalkHelper.get_all_departments(token)
if not departments:
return jsonify({"error": "获取部门失败"}), 500
all_userids = set()
for dept in departments:
userids = DingTalkHelper.get_users_by_dept(token, dept["dept_id"])
all_userids.update(userids)
if not all_userids:
return jsonify({"error": "没有获取到用户ID"}), 500
calendar_client = DingTalkHelper.create_calendar_client()
user_cache = {}
def fetch_user_events(userid):
user_detail = DingTalkHelper.get_user_detail(token, userid)
if not user_detail:
return None
unionid = user_detail.get("unionid")
name = user_detail.get("name")
events = []
if unionid:
events = DingTalkHelper.get_user_calendar_events(calendar_client, token, unionid)
return {
"userid": userid,
"name": name,
"unionid": unionid,
"events": events
}
results = []
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = [executor.submit(fetch_user_events, uid) for uid in all_userids]
for future in concurrent.futures.as_completed(futures):
res = future.result()
if res:
results.append(res)
# 转换 events
for user_data in results:
user_data['events'] = obj_to_dict(user_data.get('events', []))
return jsonify({
"departments_count": len(departments),
"users_count": len(all_userids),
"users": results
})
@app.route('/wiki_workspaces', methods=['POST'])
def wiki_workspaces():
data = request.json or {}
app_key = data.get("app_key")
app_secret = data.get("app_secret")
if not all([app_key, app_secret]):
return jsonify({"error": "app_key, app_secre两个参数必填"}), 400
try:
token = get_access_token(app_key, app_secret)
userid = get_admin_userid(token)
operator_id = get_unionid(token, userid)
client = create_wiki_client()
workspaces_ids = list_workspaces(client, token, operator_id)
workspaces = get_workspaces_details(client, token, operator_id, workspaces_ids)
for ws in workspaces:
ws["nodes"] = list_all_nodes(client, operator_id, ws["root_node_id"], token)
workspaces_serializable = workspaces # 已经是字典列表
return jsonify({
"workspaces_count": len(workspaces_serializable),
"workspaces": workspaces_serializable
})
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route("/get_all_users_wiki", methods=["POST"])
def get_all_users_wiki():
data = request.json or {}
app_key = data.get("app_key")
app_secret = data.get("app_secret")
if not all([app_key, app_secret]):
return jsonify({"error": "app_key 和 app_secret 必填"}), 400
try:
token = get_access_token(app_key, app_secret)
dept_ids = [1] + get_department_list(token)
all_users = set()
for dept_id in dept_ids:
all_users.update(get_department_users(token, dept_id))
client = create_wiki_client()
result = []
for userid in all_users:
operator_id = get_unionid(token, userid)
if not operator_id:
continue
root_node_id = get_user_root_node_id(client, token, operator_id)
if not root_node_id:
continue
nodes = list_all_nodes(client, operator_id, root_node_id, token)
result.append({
"userid": userid,
"operator_id": operator_id,
"root_node_id": root_node_id,
"nodes": nodes
})
return jsonify({"users": result, "total_users": len(result)})
except Exception as e:
return jsonify({"error": str(e)}), 500
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8888, debug=True)