__init__.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. import json
  2. import random
  3. from sqlalchemy import create_engine, select
  4. from utils.StripTagsHTMLParser import *
  5. from sqlalchemy.orm import Session
  6. from sqlalchemy import text, exists, and_, or_, not_
  7. import traceback
  8. from models import *
  9. from common.db import db_task
  10. from common.security import valid_access_token
  11. from datetime import datetime, timedelta
  12. from fastapi import APIRouter, Depends, HTTPException, Response, Query
  13. from database import get_db
  14. from pydantic import BaseModel
  15. from utils import *
  16. import copy
  17. from common.db import db_event_management, db_user
  18. router = APIRouter()
  19. @router.post('/create')
  20. async def create_task(
  21. request: Request,
  22. db: Session = Depends(get_db),
  23. body=Depends(remove_xss_json),
  24. user_id=Depends(valid_access_token)):
  25. try:
  26. # 验证必需的字段
  27. required_fields = ['task_description', 'unit_name', 'registrar','event_code']
  28. missing_fields = [field for field in required_fields if field not in body]
  29. if missing_fields:
  30. raise HTTPException(status_code=401, detail=f"Missing required fields: {', '.join(missing_fields)}")
  31. event_code = db.query(EventBase).filter(EventBase.event_code == body.get('event_code')).first()
  32. if not event_code:
  33. return Response(content="事件不存在", status_code=400)
  34. task_id = db_task.get_next_event_id(db)
  35. imgList = []
  36. if 'imgList' in body:
  37. imgList = body['imgList']
  38. del body['imgList']
  39. fileList = []
  40. if 'fileList' in body:
  41. fileList = body['fileList']
  42. del body['fileList']
  43. task_base = TaskRegistration(
  44. **body,
  45. task_id = task_id,
  46. registrar_id = user_id
  47. )
  48. db.add(task_base)
  49. db.commit()
  50. db.refresh(task_base)
  51. for file in imgList:
  52. file_name = file['url']
  53. file_name_desc = file['name']
  54. status = file['status']
  55. new_file = TaskFile(
  56. file_id=new_guid(),
  57. foreign_key=task_base.id,
  58. from_scenario='task_img',
  59. file_name=file_name,
  60. file_name_desc=file_name_desc,
  61. status=status
  62. )
  63. db.add(new_file)
  64. db.commit()
  65. for file in fileList:
  66. file_name = file['url']
  67. file_name_desc = file['name']
  68. status = file['status']
  69. new_file = TaskFile(
  70. file_id=new_guid(),
  71. foreign_key=task_base.id,
  72. from_scenario='task_file',
  73. file_name=file_name,
  74. file_name_desc=file_name_desc,
  75. status=status
  76. )
  77. db.add(new_file)
  78. db.commit()
  79. return {
  80. "code": 200,
  81. "msg": "任务创建成功",
  82. "data": task_id
  83. }
  84. except Exception as e:
  85. db.rollback()
  86. traceback.print_exc()
  87. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  88. class TaskQuery(BaseModel):
  89. task_id: str = None
  90. task_description: str = None
  91. unit_name: str = None
  92. registrar: str = None
  93. creation_time: str = None
  94. processing_status: str = None
  95. @router.post('/select')
  96. @router.get('/select')
  97. async def select_tasks(
  98. request: Request,
  99. db: Session = Depends(get_db),
  100. query: TaskQuery = Depends(),
  101. sortBy: str = Query(None, description="排序字段"),
  102. sortOrder: str = Query(None, description="排序顺序"),
  103. user_id=Depends(valid_access_token),
  104. pageNum: int = Query(1, gt=0, description="页码"),
  105. event_code: str = Query(None, description="事件ID"),
  106. pageSize: int = Query(10, gt=0, le=100, description="每页大小")):
  107. try:
  108. missing_event_code = db.query(EventBase).filter(EventBase.event_code == event_code).first()
  109. # print(missing_event_code)
  110. if not missing_event_code:
  111. return Response(content="事件不存在", status_code=400)
  112. data_query = db.query(TaskRegistration).filter(TaskRegistration.del_flag != '2')
  113. data_query = data_query.filter(TaskRegistration.event_code == event_code)
  114. # 应用过滤条件
  115. if query.task_id:
  116. data_query = data_query.filter(TaskRegistration.task_id == query.task_id)
  117. if query.task_description:
  118. data_query = data_query.filter(TaskRegistration.task_description == query.task_description)
  119. if query.unit_name:
  120. data_query = data_query.filter(TaskRegistration.unit_name == query.unit_name)
  121. if query.registrar:
  122. data_query = data_query.filter(TaskRegistration.registrar == query.registrar)
  123. if query.creation_time:
  124. data_query = data_query.filter(TaskRegistration.creation_time == query.creation_time)
  125. if query.processing_status:
  126. data_query = data_query.filter(TaskRegistration.processing_status == query.processing_status)
  127. # print(TaskRegistration,sortBy)
  128. if sortBy:
  129. if hasattr(TaskRegistration, sortBy):
  130. print("xx")
  131. sort_attr = getattr(TaskRegistration, sortBy)
  132. data_query = data_query.order_by(sort_attr.asc() if sortOrder == 'asc' else sort_attr.desc())
  133. total_count = data_query.count()
  134. offset = (pageNum - 1) * pageSize
  135. data_query = data_query.offset(offset).limit(pageSize)
  136. rows = data_query.all()
  137. data = []
  138. for row in rows:
  139. info = get_model_dict(row)
  140. info['expire_time'] = get_date_str(info['expire_time'])
  141. info['imgList'] = db_task.get_image_file_list(db, info['task_id'])
  142. info['fileList'] = db_task.get_task_file_list(db, info['task_id'])
  143. data.append(info)
  144. return {
  145. "code": 200,
  146. "msg": "任务查询成功",
  147. "data": data,
  148. "total": total_count,
  149. "pages": (total_count + pageSize - 1) // pageSize,
  150. "current_page": pageNum,
  151. "page_size": pageSize
  152. }
  153. except Exception as e:
  154. db.rollback()
  155. traceback.print_exc()
  156. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  157. @router.put('/update')
  158. async def update_task_status(
  159. request: Request,
  160. db: Session = Depends(get_db),
  161. user_id=Depends(valid_access_token)):
  162. try:
  163. body = await request.json()
  164. task_id_to_use = body.get('task_id')
  165. processing_status = body.get('processing_status')
  166. feedback_content = body.get('feedback_content')
  167. attachList = body.get('attachList')
  168. event_code = db.query(EventBase).filter(EventBase.event_code == body.get('event_code')).first()
  169. if not event_code:
  170. return Response(content="事件不存在", status_code=400)
  171. if not task_id_to_use:
  172. return Response(content="Missing required parameter 'task_id'", status_code=400)
  173. if processing_status not in ['已完成', '处理中', '待处理','未完成']:
  174. return Response(content="processing_status must be '已完成' or '处理中' or '待处理' or '未完成'", status_code=400)
  175. task_entry = (db.query(TaskRegistration)
  176. .filter(TaskRegistration.del_flag != '2')
  177. .filter(TaskRegistration.task_id == task_id_to_use))
  178. task_entry = task_entry.first()
  179. if not task_entry:
  180. raise HTTPException(status_code=404, detail="任务不存在")
  181. new_feeback = TaskFeeback(
  182. task_id = task_id_to_use,
  183. feeback_user = task_entry.registrar,
  184. content = feedback_content,
  185. processing_status = processing_status,
  186. create_time = datetime.now(),
  187. feeback_type = "0",
  188. leader_unit = "",
  189. leader_name = "",
  190. approval_content = "",
  191. recorded_by=user_id
  192. )
  193. db.add(new_feeback)
  194. db.commit()
  195. task_entry.processing_status = processing_status
  196. task_entry.update_time = datetime.now()
  197. db.commit()
  198. if attachList is not None:
  199. for file in attachList:
  200. file_name = file['url']
  201. file_name_desc = file['name']
  202. status = file['status']
  203. new_file = TaskFile(
  204. file_id=new_guid(),
  205. foreign_key=task_id_to_use,
  206. from_scenario='task_feeback',
  207. file_name=file_name,
  208. file_name_desc=file_name_desc,
  209. status=status
  210. )
  211. db.add(new_file)
  212. db.commit()
  213. return {
  214. "code": 200,
  215. "msg": "任务状态更新成功",
  216. "data": {
  217. "task_id": task_id_to_use,
  218. "processing_status": task_entry.processing_status,
  219. "update_time": task_entry.update_time.isoformat()
  220. }
  221. }
  222. except Exception as e:
  223. traceback.print_exc()
  224. raise HTTPException(status_code=500, detail=str(e))
  225. @router.delete('/delete')
  226. async def delete_task(
  227. request: Request,
  228. db: Session = Depends(get_db),
  229. user_id=Depends(valid_access_token)):
  230. try:
  231. body = await request.json()
  232. task_id_to_use = body.get('taskID')
  233. if not task_id_to_use:
  234. raise HTTPException(status_code=400, detail="Missing required parameter 'taskID'")
  235. event_code = db.query(EventBase).filter(EventBase.event_code == body.get('event_code')).first()
  236. if not event_code:
  237. return Response(content="事件不存在", status_code=400)
  238. task_entry = db.query(TaskRegistration).filter(TaskRegistration.task_id == task_id_to_use).first()
  239. if not task_entry:
  240. raise HTTPException(status_code=404, detail="任务不存在")
  241. task_entry.del_flag = '2'
  242. try:
  243. db.commit()
  244. return {
  245. "code": 200,
  246. "msg": "任务删除成功",
  247. "data": {
  248. "task_id": task_entry.task_id
  249. }
  250. }
  251. except Exception as e:
  252. db.rollback()
  253. raise HTTPException(status_code=500, detail=f"An error occurred while deleting the task: {str(e)}")
  254. except HTTPException as e:
  255. raise e
  256. except Exception as e:
  257. db.rollback()
  258. raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
  259. @router.get('/selectUnit')
  260. async def select_unit(
  261. request: Request,
  262. db: Session = Depends(get_db),
  263. query: TaskQuery = Depends(),
  264. user_id=Depends(valid_access_token),
  265. ):
  266. try:
  267. data_query = db.query(TaskUnit).filter(TaskUnit.id != '2').all()
  268. return {
  269. "code": 200,
  270. "msg": "查询成功",
  271. "data": data_query
  272. }
  273. except HTTPException as e:
  274. raise e
  275. except Exception as e:
  276. db.rollback()
  277. raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
  278. #
  279. # 小屏专用,不敢搞大屏相关代码
  280. #
  281. @router.get('/list')
  282. async def select_tasks(
  283. request: Request,
  284. task_type: str = Query(None),
  285. processing_status: str = Query(None),
  286. search_keyword: str = Query(None),
  287. page: int = Query(1, gt=0, description="页码"),
  288. page_size: int = Query(10, gt=0, le=100, description="每页大小"),
  289. db: Session = Depends(get_db)):
  290. try:
  291. data_query = db.query(TaskRegistration).filter(TaskRegistration.del_flag != '2').filter(TaskRegistration.event_code is not None)
  292. # 应用过滤条件
  293. if task_type is not None:
  294. data_query = data_query.filter(TaskRegistration.task_type == task_type)
  295. if search_keyword is not None:
  296. data_query = data_query.filter(TaskRegistration.task_description.like('%{}%'.format(search_keyword)))
  297. if processing_status is not None:
  298. data_query = data_query.filter(TaskRegistration.processing_status == processing_status)
  299. total_count = data_query.count()
  300. offset = (page - 1) * page_size
  301. data_query = data_query.order_by(TaskRegistration.creation_time.desc()).offset(offset).limit(page_size)
  302. data = []
  303. tasks = data_query.all()
  304. for n in tasks:
  305. task = get_model_dict(n)
  306. task['creation_time'] = get_datetime_str(task['creation_time'])
  307. task['event_name'] = db_event_management.get_event_title(db, n.event_code)
  308. data.append(task)
  309. return {
  310. "code": 200,
  311. "msg": "任务查询成功",
  312. "data": data,
  313. "total": total_count
  314. }
  315. except Exception as e:
  316. traceback.print_exc()
  317. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  318. @router.post("/leader_request")
  319. async def leader_request(
  320. request: Request,
  321. db: Session = Depends(get_db),
  322. body = Depends(remove_xss_json),
  323. user_id = Depends(valid_access_token)
  324. ):
  325. try:
  326. task_id = body['task_id']
  327. processing_status = body['processing_status']
  328. new_feeback = TaskFeeback(
  329. **body,
  330. recorded_by=user_id
  331. )
  332. db.add(new_feeback)
  333. db.commit()
  334. db.query(TaskRegistration).filter(TaskRegistration.task_id == task_id).update({"processing_status": processing_status, "update_time": datetime.now()})
  335. db.commit()
  336. return {
  337. "code": 200,
  338. "msg": "请示领导保存成功"
  339. }
  340. except Exception as e:
  341. # 处理异常
  342. db.rollback()
  343. traceback.print_exc()
  344. raise HTTPException(status_code=500, detail=str(e))
  345. @router.post("/feeback")
  346. async def feeback(
  347. request: Request,
  348. db: Session = Depends(get_db),
  349. body = Depends(remove_xss_json),
  350. user_id = Depends(valid_access_token)
  351. ):
  352. try:
  353. feeback_user = get_req_param_optional(body, 'feeback_user')
  354. task_id = body['task_id']
  355. processing_status = body['processing_status']
  356. new_file_list = []
  357. if 'fileList' in body:
  358. new_file_list = copy.deepcopy(body['fileList'])
  359. del body['fileList']
  360. if feeback_user == '':
  361. feeback_user = db_user.get_user_info(db, user_id).nick_name
  362. if 'feeback_user' in body:
  363. del body['feeback_user']
  364. new_feeback = TaskFeeback(
  365. **body,
  366. feeback_user=feeback_user,
  367. recorded_by=user_id
  368. )
  369. db.add(new_feeback)
  370. db.commit()
  371. db.refresh(new_feeback)
  372. print(new_file_list)
  373. for file in new_file_list:
  374. file_name = file['file_name']
  375. file_name_desc = file['file_name_desc']
  376. status = file['status']
  377. new_file = TaskFile(
  378. file_id=new_guid(),
  379. foreign_key=new_feeback.id,
  380. from_scenario='task_feeback',
  381. file_name=file_name,
  382. file_name_desc=file_name_desc,
  383. status=status
  384. )
  385. db.add(new_file)
  386. db.commit()
  387. db.query(TaskRegistration).filter(TaskRegistration.task_id == task_id).update({"processing_status": processing_status, "update_time": datetime.now()})
  388. db.commit()
  389. return {
  390. "code": 200,
  391. "msg": "任务反馈保存成功"
  392. }
  393. except Exception as e:
  394. # 处理异常
  395. db.rollback()
  396. traceback.print_exc()
  397. raise HTTPException(status_code=500, detail=str(e))
  398. @router.get('/detail')
  399. async def get_task_detail(
  400. request: Request,
  401. task_id: str = Query(None, description='任务编号'),
  402. db: Session = Depends(get_db)):
  403. print('task_id:',task_id)
  404. try:
  405. # 构建查询
  406. rows = db.query(TaskFeeback).filter(and_(TaskFeeback.task_id == task_id)).all()
  407. feebacks = []
  408. for row in rows:
  409. fileList = []
  410. # 附件
  411. rows = db.query(TaskFile).filter(and_(TaskFile.from_scenario=="task_feeback", TaskFile.foreign_key == row.id, InfoPublishFile.del_flag == '0')).all()
  412. fileList = [
  413. {
  414. "name": row.file_name,
  415. "url": row.storage_file_name
  416. }
  417. for row in rows
  418. ]
  419. info = get_model_dict(row)
  420. info['create_time'] = get_datetime_str(row.create_time)
  421. info['approval_time'] = get_datetime_str(row.approval_time)
  422. info['fileList'] = fileList
  423. info['fileCount'] = len(fileList)
  424. feebacks.append(info)
  425. query = db.query(TaskRegistration)
  426. query = query.filter(TaskRegistration.task_id == task_id)
  427. # 执行查询
  428. row = query.first()
  429. if row is not None:
  430. return {
  431. "code": 200,
  432. "msg": "查询成功",
  433. "data": {
  434. "id": row.id,
  435. "task_id": row.task_id,
  436. "task_type": row.task_type,
  437. "event_code": row.event_code,
  438. "event_name": db_event_management.get_event_title(db, row.event_code),
  439. "processing_status": row.processing_status,
  440. "expire_time": get_datetime_str(row.expire_time),
  441. "update_time": get_datetime_str(row.update_time),
  442. "feeback_user": row.feeback_user,
  443. "task_description": row.task_description,
  444. "feebacks": feebacks
  445. }
  446. }
  447. else:
  448. return {
  449. "code": 500,
  450. "msg": "查询失败"
  451. }
  452. except Exception as e:
  453. # 处理异常
  454. traceback.print_exc()
  455. raise HTTPException(status_code=500, detail=str(e))
  456. # 请示列表
  457. @router.get('/request/list')
  458. async def select_tasks(
  459. request: Request,
  460. task_type: str = Query(None),
  461. processing_status: str = Query(None),
  462. search_keyword: str = Query(None),
  463. page: int = Query(1, gt=0, description="页码"),
  464. page_size: int = Query(10, gt=0, le=100, description="每页大小"),
  465. db: Session = Depends(get_db)):
  466. try:
  467. data_query = db.query(TaskFeeback).filter(TaskFeeback.feeback_type == '1')
  468. # 应用过滤条件
  469. if task_type is not None:
  470. subquery = db.query(TaskRegistration.task_id).filter(and_(TaskRegistration.del_flag == '0', TaskRegistration.task_type == task_type)).subquery()
  471. data_query = data_query.filter(TaskFeeback.task_id == subquery.c.task_id)
  472. if processing_status is not None:
  473. data_query = data_query.filter(TaskFeeback.processing_status == processing_status)
  474. if search_keyword is not None:
  475. data_query = data_query.filter(TaskFeeback.content.like('%{}%'.format(search_keyword)))
  476. total_count = data_query.count()
  477. offset = (page - 1) * page_size
  478. data_query = data_query.order_by(TaskFeeback.create_time.desc()).offset(offset).limit(page_size)
  479. data = []
  480. tasks = data_query.all()
  481. for n in tasks:
  482. task = get_model_dict(n)
  483. task['nick_name'] = db_user.get_nick_name_by_id(db, task['recorded_by'])
  484. task['create_time'] = get_datetime_str(task['create_time'])
  485. task['approval_time'] = get_datetime_str(task['approval_time'])
  486. task['update_time'] = task['create_time']
  487. if task['approval_time'] != None:
  488. task['update_time'] = task['approval_time']
  489. task['event_name'] = ''
  490. task_id = task['task_id']
  491. reg_info = db.query(TaskRegistration).filter(TaskRegistration.task_id == task_id).first()
  492. if reg_info is not None:
  493. reg_info = get_model_dict(reg_info)
  494. task['event_name'] = db_event_management.get_event_title(db, reg_info['event_code'])
  495. data.append(task)
  496. return {
  497. "code": 200,
  498. "msg": "请示查询成功",
  499. "data": data,
  500. "total": total_count
  501. }
  502. except Exception as e:
  503. traceback.print_exc()
  504. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  505. # 请示批复
  506. @router.post("/approval")
  507. async def approval(
  508. request: Request,
  509. db: Session = Depends(get_db),
  510. body = Depends(remove_xss_json),
  511. user_id = Depends(valid_access_token)
  512. ):
  513. try:
  514. feeback_id = get_req_param(body, "feeback_id")
  515. approval_content = get_req_param_optional(body, 'approval_content')
  516. row = db.query(TaskFeeback).filter(TaskFeeback.id == feeback_id).first()
  517. if row is None:
  518. return {
  519. "code": 500,
  520. "msg": "请示不存在"
  521. }
  522. row.approval_content = approval_content
  523. row.approval_time = datetime.now()
  524. row.processing_status = '已完成'
  525. db.commit()
  526. return {
  527. "code": 200,
  528. "msg": "请示批复保存成功"
  529. }
  530. except Exception as e:
  531. # 处理异常
  532. db.rollback()
  533. traceback.print_exc()
  534. raise HTTPException(status_code=500, detail=str(e))