addressbook.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. from fastapi import APIRouter, Request, Depends, HTTPException, Query, Body
  2. from sqlalchemy.exc import IntegrityError
  3. from fastapi.responses import HTMLResponse, FileResponse
  4. from fastapi.responses import JSONResponse
  5. from database import get_db
  6. from sqlalchemy import text, exists, and_, or_, not_
  7. from sqlalchemy.orm import Session
  8. from models import *
  9. import json
  10. import random
  11. from sqlalchemy import create_engine, select
  12. from typing import Optional
  13. from utils.StripTagsHTMLParser import *
  14. from common.db import db_event_management, db_user, db_area, db_emergency_plan
  15. from common.security import valid_access_token
  16. import traceback
  17. from utils import *
  18. import uuid
  19. from utils.ry_system_util import *
  20. from datetime import datetime, timedelta
  21. from common.db import db_dict
  22. from urllib.parse import quote
  23. import base64
  24. from config import settings
  25. from pydantic import BaseModel
  26. from typing import List, Dict,Set
  27. router = APIRouter()
  28. def get_dept_tree(db: Session, dept_id: int=0, tag_ids: Optional[Set[int]] = None) -> Dict:
  29. dept = db.query(SysDept).filter(SysDept.dept_id == dept_id).first()
  30. if not dept:
  31. return None
  32. # 收集祖先部门名称
  33. ancestors_names = []
  34. current_dept = dept
  35. while current_dept:
  36. ancestors_names.append(current_dept.dept_name)
  37. current_dept = db.query(SysDept).filter(SysDept.dept_id == current_dept.parent_id).first()
  38. ancestors_names.reverse()
  39. # 获取部门标签
  40. dept_tags = db.query(SysDeptTag).filter(SysDeptTag.dept_id == dept.dept_id).all()
  41. dept_tags_info = [{"tag_id": tag.tag_id, "tag_name": tag.tag_name} for tag in db.query(DeptTag).filter(DeptTag.tag_id.in_([tag.tag_id for tag in dept_tags])).all()]
  42. # 如果提供了标签ID参数,检查部门是否有匹配的标签
  43. if tag_ids and not any(tag['tag_id'] in tag_ids for tag in dept_tags_info):
  44. # 如果没有匹配的标签,检查子部门是否有匹配的标签
  45. child_with_tag = False
  46. for child in db.query(SysDept).filter(SysDept.parent_id == dept.dept_id).all():
  47. if get_dept_tree(db, child.dept_id, tag_ids) is not None:
  48. child_with_tag = True
  49. break
  50. if not child_with_tag:
  51. return None # 如果子部门也没有匹配的标签,则不包含该部门
  52. # 获取用户标签
  53. def get_user_tags(user_id):
  54. user_tags_subquery = db.query(SysUserTag.tag_id).filter(SysUserTag.user_id == user_id).subquery()
  55. tags = db.query(SysTag).filter(SysTag.tag_id.in_(user_tags_subquery)).all()
  56. return [{"tag_id": tag.tag_id, "tag_name": tag.tag_name} for tag in tags]
  57. # 获取部门下的用户
  58. users_info = []
  59. for user in db.query(SysUser).filter(SysUser.dept_id == dept.dept_id).all():
  60. user_tags_info = get_user_tags(user.user_id)
  61. # 如果提供了标签ID参数,检查用户是否有匹配的标签
  62. if tag_ids and not any(tag['tag_id'] in tag_ids for tag in user_tags_info):
  63. continue # 如果用户没有匹配的标签,则不包含该用户
  64. users_info.append({
  65. "user_id": user.user_id,
  66. "dept_id": user.dept_id,
  67. "position": "无",
  68. "user_name": user.user_name,
  69. "email": user.email,
  70. "user_tags": user_tags_info
  71. })
  72. # 构建子部门树
  73. child_trees = [get_dept_tree(db, child.dept_id, tag_ids) for child in db.query(SysDept).filter(SysDept.parent_id == dept.dept_id).all()]
  74. child_trees = [child for child in child_trees if child]
  75. dept_info = {
  76. "dept_id": dept.dept_id,
  77. "parent_id": dept.parent_id,
  78. "ancestors": '/'.join(ancestors_names),
  79. "dept_name": dept.dept_name,
  80. "tags": dept_tags_info,
  81. "users": users_info,
  82. "children": child_trees
  83. }
  84. return dept_info
  85. def get_dept_tree2(db: Session, tag_id: int = None) -> Dict:
  86. dept_tree = []
  87. def get_user_tags(user_id):
  88. user_tags_subquery = db.query(SysUserTag.tag_id).filter(SysUserTag.user_id == user_id).subquery()
  89. tags = db.query(SysTag).filter(SysTag.tag_id.in_(user_tags_subquery)).all()
  90. return [{"tag_id": tag.tag_id, "tag_name": tag.tag_name} for tag in tags]
  91. def build_dept_tree(depts, parent_dept):
  92. dept_tree = []
  93. for dept_info in depts:
  94. dept = {
  95. "uuid":str(uuid.uuid4()).replace('-',''),
  96. "id": dept_info.dept_id,
  97. "label": dept_info.dept_name,
  98. "deptType": True
  99. }
  100. # print(dept_info.dept_id)
  101. users = db.query(SysUser).filter(SysUser.dept_id == dept_info.dept_id).filter(SysUser.del_flag != '2').all()
  102. for user_info in users:
  103. user = {
  104. "uuid": str(uuid.uuid4()).replace('-', ''),
  105. "id": user_info.user_id,
  106. "label": user_info.nick_name,
  107. "deptType": False,
  108. "userTag":get_user_tags(user_info.user_id),
  109. "userDept":dept_info.dept_name,
  110. "positon":'',
  111. "avatar":user_info.avatar
  112. }
  113. if "children" in dept:
  114. dept['children'].append(user)
  115. else:
  116. dept['children']=[user]
  117. children = parent_id_get_dept_info(db, dept_info.dept_id)
  118. if len(children) > 0:
  119. children_depts = build_dept_tree(children, dept)
  120. if "children" in dept:
  121. dept['children'] += children_depts
  122. else:
  123. dept["children"] = children_depts
  124. dept_tree.append(dept)
  125. return dept_tree
  126. if tag_id is None:
  127. # dept_ids = [0]
  128. # for dept_id in dept_ids:
  129. dept_tree=build_dept_tree(parent_id_get_dept_info(db, 0), None)
  130. else:
  131. dept_infos = []
  132. dept_ids = db.query(SysDeptTag).filter(SysDeptTag.tag_id == tag_id).all()
  133. for dept_id in dept_ids:
  134. c_id = dept_id.dept_id
  135. dept_infos.append(dept_id_get_dept_info(db,c_id))
  136. dept_tree=build_dept_tree(dept_infos, None)
  137. return dept_tree
  138. @router.get("/alldepts", response_model=Dict)
  139. def read_all_depts(db: Session = Depends(get_db), tag_id: int= Query(None, title="Tag IDs")):
  140. # tag_ids_set = tag_id
  141. # top_level_depts = get_dept_tree(db, 3, tag_ids_set)
  142. # if not top_level_depts:
  143. # raise HTTPException(status_code=404, detail="Department not found")
  144. # return [top_level_depts]
  145. data = get_dept_tree2(db,tag_id)
  146. return {
  147. "code": 200,
  148. "msg": "成功",
  149. "data": data
  150. }
  151. class DeptTagInfo(BaseModel):
  152. tag_id: int
  153. tag_name: str
  154. @router.get("/depts", response_model=Dict)
  155. def get_dept(db: Session = Depends(get_db)):
  156. dept_tags = db.query(DeptTag).all()
  157. # 如果没有找到记录,返回404错误
  158. if not dept_tags:
  159. raise HTTPException(status_code=404, detail="No dept tags found")
  160. dept_tags_data = [
  161. DeptTagInfo(tag_id=dept_tag.tag_id,tag_name=dept_tag.tag_name)
  162. for dept_tag in dept_tags
  163. ]
  164. return {
  165. "code": 200,
  166. "msg": "成功",
  167. "data": dept_tags_data
  168. }
  169. class User(BaseModel):
  170. user_id: int
  171. user_name: str
  172. # nick_name: str
  173. class TagIDs(BaseModel):
  174. tag_ids: List[int]
  175. @router.post("/users_by_tags")
  176. def read_users_by_tags(
  177. db: Session = Depends(get_db),
  178. tag_ids_data: TagIDs = Body(...)
  179. ):
  180. # 提取tag_ids
  181. tag_ids = tag_ids_data.tag_ids
  182. if not tag_ids:
  183. raise HTTPException(status_code=400, detail="Tag IDs are required")
  184. # 构建查询条件
  185. conditions = [SysUserTag.tag_id == tag_id for tag_id in tag_ids]
  186. query = db.query(SysUser).join(SysUserTag, SysUser.user_id == SysUserTag.user_id).filter(or_(*conditions))
  187. distinct_user_count = db.query(SysUserTag.user_id).filter(SysUserTag.tag_id.in_(tag_ids)).count()
  188. # 执行查询并去重 这里的去重只是单纯的用户标签去重,如果有多用户的得看到时候实际数据再规划如何去重
  189. users_with_tags = query.distinct().all()
  190. non_distinct_user_count = len(users_with_tags)
  191. print(distinct_user_count,non_distinct_user_count)
  192. # 如果没有找到用户,返回404错误
  193. if not users_with_tags:
  194. raise HTTPException(status_code=404, detail="No users found for the given tag IDs")
  195. # 将用户模型转换为User Pydantic模型列表
  196. users_data = [
  197. User(user_id=user.user_id, user_name=user.user_name)
  198. for user in users_with_tags
  199. ]
  200. return {
  201. "code": 200,
  202. "msg": "成功",
  203. "distinct_user_count":distinct_user_count,
  204. "non_distinct_user_count":non_distinct_user_count,
  205. "data": users_data
  206. }
  207. class TagTree(BaseModel):
  208. tag_id: int
  209. tag_name: str
  210. parent_id: int
  211. children: List['TagTree'] = []
  212. # 递归构建树形结构
  213. def build_tree(tags, parent_id=0):
  214. tree = []
  215. for tag in tags:
  216. if tag.parent_id == parent_id:
  217. children = build_tree(tags, tag.tag_id)
  218. tree.append(TagTree(tag_id=tag.tag_id, tag_name=tag.tag_name, parent_id=tag.parent_id, children=children))
  219. return tree
  220. @router.post("/tags_tree")
  221. def get_tag_tree(
  222. db: Session = Depends(get_db),
  223. tag_ids_data: TagIDs = Body(...)
  224. ):
  225. # 提取tag_ids
  226. tag_ids = tag_ids_data.tag_ids
  227. if not tag_ids:
  228. raise HTTPException(status_code=400, detail="Tag IDs are required")
  229. # 查询所有相关的标签
  230. tags = db.query(SysTag).filter(SysTag.tag_id.in_(tag_ids)).all()
  231. # 如果没有找到标签,返回404错误
  232. if not tags:
  233. raise HTTPException(status_code=404, detail="Tags not found for the given tag IDs")
  234. # 构建标签树
  235. tag_tree = build_tree(tags)
  236. return {
  237. "code": 200,
  238. "msg": "成功",
  239. "data": tag_tree
  240. }
  241. class TagData(BaseModel):
  242. user_ids: List[int]
  243. tag_name: str
  244. @router.post("/add_common_list_tags")
  245. def add_common_list_tags(
  246. db: Session = Depends(get_db),
  247. data: TagData = Body(...)
  248. ):
  249. user_ids = data.user_ids
  250. tag_name = data.tag_name
  251. if not user_ids or not tag_name:
  252. raise HTTPException(status_code=tag_name, detail="User IDs and Tag Name are required")
  253. # 查询标签是否存在
  254. tag = db.query(Common_List_Tags).filter(Common_List_Tags.tag_name == tag_name).first()
  255. print(tag)
  256. # print(tag.tag_id)
  257. # 如果标签不存在,则创建新标签
  258. if not tag:
  259. tag = Common_List_Tags(tag_name=tag_name)
  260. db.add(tag)
  261. db.commit()
  262. tag_id = tag.tag_id
  263. else:
  264. tag_id = tag.tag_id
  265. # 为每个用户ID插入记录,如果已存在则跳过
  266. for user_id in user_ids:
  267. existing_record = db.query(Sys_Common_List_Tags).filter_by(user_id=user_id, tag_id=tag_id).first()
  268. if not existing_record:
  269. db.add(Sys_Common_List_Tags(user_id=user_id, tag_id=tag_id))
  270. db.commit()
  271. return {"code": 200,"msg": "操作成功", "tag_id": tag_id}
  272. class TagUserCount(BaseModel):
  273. tag_id: int
  274. tag_name: str
  275. user_count: int
  276. @router.get("/tags_user_count", response_model=Dict)
  277. def get_tags_user_count(db: Session = Depends(get_db)):
  278. # 查询所有标签
  279. tags = db.query(Common_List_Tags).all()
  280. # 如果没有找到标签,返回404错误
  281. if not tags:
  282. raise HTTPException(status_code=404, detail="No tags found")
  283. # 构建结果列表
  284. result = []
  285. for tag in tags:
  286. # 查询与标签相关的用户数量
  287. user_count = db.query(Sys_Common_List_Tags).filter(Sys_Common_List_Tags.tag_id == tag.tag_id).count()
  288. result.append(TagUserCount(tag_id=tag.tag_id, tag_name=tag.tag_name, user_count=user_count))
  289. return {
  290. "code": 200,
  291. "msg": "成功",
  292. "data": result
  293. }