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)