back.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. from fastapi import APIRouter, Request, Depends, HTTPException, Query
  4. from sqlalchemy.exc import IntegrityError
  5. from fastapi.responses import HTMLResponse, FileResponse
  6. from fastapi.responses import JSONResponse
  7. from database import get_db
  8. from sqlalchemy import text, exists, and_, or_, not_
  9. from sqlalchemy.orm import Session
  10. from models import *
  11. import json
  12. import os
  13. from sqlalchemy import create_engine, select
  14. from typing import Optional
  15. from utils.StripTagsHTMLParser import *
  16. from common.db import db_event_management, db_user, db_area, db_emergency_plan
  17. from common.security import valid_access_token
  18. import traceback
  19. from utils import *
  20. from datetime import datetime, timedelta
  21. from common import YzyApi
  22. from common.db import db_dict
  23. from urllib.parse import quote
  24. import base64
  25. from config import settings
  26. router = APIRouter()
  27. EXAMINE_TYPE_DICT = {
  28. 0: "草稿",
  29. 10: "提交",
  30. 20: "领导审批",
  31. 30: "重新提交"
  32. }
  33. EXAMINE_SUB_TYPE_DICT = {
  34. 0: "草稿",
  35. 10: "提交",
  36. 20: "待审批",
  37. 21: "审批通过",
  38. 22: "审批不通过",
  39. 30: "重新提交"
  40. }
  41. # 信息发布创建
  42. @router.post('/create')
  43. async def create_emergency_plan(
  44. db: Session = Depends(get_db),
  45. body = Depends(remove_xss_json),
  46. user_id = Depends(valid_access_token)
  47. ):
  48. try:
  49. dept_id = 0
  50. dept_name = ''
  51. user_row = db.query(SysUser).filter(SysUser.user_id == user_id).first()
  52. user_name = user_row.user_name
  53. nick_name = user_row.nick_name
  54. dept_id = user_row.dept_id
  55. dept_row = db.query(SysDept).filter(SysDept.dept_id == dept_id).first()
  56. dept_name = dept_row.dept_name
  57. new_publish = InfoPublishBase(
  58. title = body['title'],
  59. publish_group = body['publish_group'],
  60. template_id = body['template_id'],
  61. content = body['content'],
  62. recorded_by = user_id,
  63. del_flag = '0',
  64. dept_id = dept_id,
  65. dept_name = dept_name,
  66. add_time = datetime.now(),
  67. response_type = body['response_type'],
  68. publish_time = body['publish_time'],
  69. examine_by = body['examine_by'],
  70. publish_status = 0,
  71. examine_status = 0,
  72. publish_channel = body['publish_channel'],
  73. user_count = body['user_count'],
  74. user_ok_count = 0,
  75. user_err_count = 0,
  76. user_sending_count = 0
  77. )
  78. db.add(new_publish)
  79. db.commit()
  80. db.refresh(new_publish)
  81. new_publish_id = new_publish.id
  82. # 发送人员
  83. for u in body['users']:
  84. send_user_id = u['user_id']
  85. send_nick_name = u['nick_name']
  86. send_user_name = ''
  87. send_dept_name = ''
  88. user_row = db.query(SysUser).filter(SysUser.user_id == send_user_id).first()
  89. if user_row is not None:
  90. send_user_name = user_row.user_name
  91. send_dept_row = db.query(SysDept).filter(SysDept.dept_id == user_row.dept_id).first()
  92. send_dept_name = send_dept_row.dept_name
  93. new_resp = InfoPublishResponses(
  94. publish_id = new_publish_id,
  95. user_id = send_user_id,
  96. user_name = send_user_name,
  97. nick_name = send_nick_name,
  98. dept_name = send_dept_name,
  99. sent_status = 0,
  100. response_type = body['response_type'],
  101. publish_channel = body['publish_channel']
  102. )
  103. db.add(new_resp)
  104. db.commit()
  105. # 附件
  106. if 'attachs' in body:
  107. infopublish_files = [
  108. InfoPublishFile(
  109. file_name=fileName["name"],
  110. storage_file_name=fileName["url"],
  111. file_path=f'/data/upload/mergefile/uploads/{fileName["url"]}',
  112. file_size=os.path.getsize(f'/data/upload/mergefile/uploads/{fileName["url"]}'),
  113. foreign_key=str(new_publish_id),
  114. from_scenario="infopublish_attach_file",
  115. update_time=datetime.now(),
  116. create_time=datetime.now(),
  117. create_by=user_id,
  118. create_dept=dept_id,
  119. del_flag='0',
  120. status=0,
  121. )
  122. for fileName in body['attachs']
  123. ]
  124. db.add_all(infopublish_files)
  125. db.commit()
  126. # 审批附件
  127. if 'examine_attachs' in body:
  128. infopublish_files = [
  129. InfoPublishFile(
  130. file_name=fileName["name"],
  131. storage_file_name=fileName["url"],
  132. file_path=f'/data/upload/mergefile/uploads/{fileName["url"]}',
  133. file_size=os.path.getsize(f'/data/upload/mergefile/uploads/{fileName["url"]}'),
  134. foreign_key=str(new_publish_id),
  135. from_scenario="infopublish_examine_attach_file",
  136. update_time=datetime.now(),
  137. create_time=datetime.now(),
  138. create_by=user_id,
  139. create_dept=dept_id,
  140. del_flag='0',
  141. status=0,
  142. )
  143. for fileName in body['examine_attachs']
  144. ]
  145. db.add_all(infopublish_files)
  146. db.commit()
  147. # 审批记录
  148. infopublish_examine = InfoPublishExamine(
  149. publish_id = new_publish_id,
  150. examine_type = 10, # 提交
  151. examine_sub_type = 10, # 提交
  152. examine_time = datetime.now(),
  153. content = '',
  154. user_id = user_id,
  155. user_name = user_name,
  156. nick_name = nick_name,
  157. del_flag = '0'
  158. )
  159. db.add(infopublish_examine)
  160. db.commit()
  161. # 改草稿、待审批状态
  162. db.query(InfoPublishBase).filter(InfoPublishBase.id == new_publish_id).update({"publish_status": 1, "examine_status": 1})
  163. db.commit()
  164. return {
  165. "code": 200,
  166. "msg": "信息创建成功",
  167. "data": new_publish_id
  168. }
  169. except Exception as e:
  170. traceback.print_exc()
  171. # 处理异常
  172. raise HTTPException(status_code=500, detail=str(e))
  173. # 信息发布分页查询
  174. @router.get('/list')
  175. async def get_publish_list(
  176. publish_group: str = Query('', description='发布单位'),
  177. publish_status: str = Query('', description='发布状态的字典键值'),
  178. examine_status: str = Query('', description='审批状态的字典键值'),
  179. dispose_status: str = Query('', description='处理状态的字典键值'),
  180. content: str = Query('', description='信息内容'),
  181. sort_by: str = Query('', description='排序字段'),
  182. sort_order: str = Query("asc", description='排序方式'),
  183. page: int = Query(1, gt=0, description='页码'),
  184. page_size: int = Query(10, gt=0, description='pageSize'),
  185. db: Session = Depends(get_db),
  186. user_id = Depends(valid_access_token)
  187. ):
  188. try:
  189. # 应用查询条件
  190. where = and_(InfoPublishBase.del_flag == '0')
  191. if content != '':
  192. where = and_(where, InfoPublishBase.content.like('%{}%'.format(content)))
  193. if publish_status not in ['', '0'] :
  194. where = and_(where, InfoPublishBase.publish_status == publish_status)
  195. if examine_status not in ['', '0'] :
  196. where = and_(where, InfoPublishBase.examine_status == examine_status)
  197. if publish_group != '':
  198. where = and_(where, InfoPublishBase.publish_group.like('%{}%'.format(publish_group)))
  199. if dispose_status not in ['', '0'] :
  200. where = and_(where, InfoPublishBase.examine_status == 1, InfoPublishBase.examine_by == user_id)
  201. print(where)
  202. # 计算总条目数
  203. q = db.query(func.count(InfoPublishBase.id))
  204. q = q.filter(where)
  205. total = q.scalar()
  206. # 执行分页查询
  207. q = db.query(InfoPublishBase)
  208. q = q.filter(where)
  209. rows = q.order_by(InfoPublishBase.id.desc()).offset((page - 1) * page_size).limit(page_size).all()
  210. data = []
  211. for row in rows:
  212. # 发布申请人
  213. recorded_by = row.recorded_by
  214. user_row = db.query(SysUser).filter(SysUser.user_id == recorded_by).first()
  215. nick_name = ""
  216. dept_name = ""
  217. if user_row is not None:
  218. nick_name = user_row.nick_name
  219. dept_id = user_row.dept_id
  220. dept_row = db.query(SysDept).filter(SysDept.dept_id == dept_id).first()
  221. if dept_row is not None:
  222. dept_name = dept_row.dept_name
  223. # 待处理人
  224. examine_user = "无"
  225. examine_by = row.examine_by
  226. user_row = db.query(SysUser).filter(SysUser.user_id == examine_by).first()
  227. if user_row is not None:
  228. examine_user = user_row.nick_name
  229. data.append({
  230. "id": row.id,
  231. "title": row.title,
  232. "info_type": row.info_type,
  233. "publish_group": row.publish_group,
  234. "content": row.content,
  235. "publish_time": get_datetime_str(row.publish_time),
  236. "publish_channel": row.publish_channel,
  237. "nick_name": nick_name,
  238. "dept_name": dept_name,
  239. "examine_user": examine_user,
  240. "publish_status": db_dict.get_dict_label(db, "mm_publish_status", row.publish_status),
  241. "examine_status": db_dict.get_dict_label(db, "mm_examine_status", row.examine_status),
  242. "user_count": row.user_count,
  243. "user_ok_count": row.user_ok_count,
  244. "user_err_count": row.user_err_count,
  245. "user_sending_count": row.user_sending_count,
  246. "is_my_edit": (row.examine_status == 0 or row.examine_status == 9) and row.recorded_by == user_id, # 是否我的编辑事项
  247. "is_my_examine": row.examine_status == 1 and int(row.examine_by) == user_id # 是否我的审批事项
  248. })
  249. # 返回结果
  250. return {
  251. "code": 200,
  252. "msg": "查询成功",
  253. "data": data,
  254. "total": total
  255. }
  256. except Exception as e:
  257. # 处理异常
  258. traceback.print_exc()
  259. raise HTTPException(status_code=500, detail=str(e))
  260. # 信息发布查看
  261. @router.get('/edit')
  262. async def get_edit_info(
  263. request: Request,
  264. info_id: str = Query(None, description='信息ID'),
  265. db: Session = Depends(get_db)):
  266. row = db.query(InfoPublishBase).filter(InfoPublishBase.id == info_id).first()
  267. data = get_model_dict(row)
  268. data['add_time'] = get_datetime_str(data['add_time'])
  269. data['publish_time'] = get_datetime_str(data['publish_time'])
  270. # 反馈 && 未反馈
  271. data['feedback_count'] = db.query(InfoPublishResponses).filter(and_(InfoPublishResponses.publish_id == info_id, InfoPublishResponses.sent_status > 0, InfoPublishResponses.response_type > 0)).count()
  272. data['unresponsive_count'] = db.query(InfoPublishResponses).filter(and_(InfoPublishResponses.publish_id == info_id, InfoPublishResponses.sent_status > 0, InfoPublishResponses.response_type > 0)).count()
  273. # 附件
  274. rows = db.query(InfoPublishFile).filter(and_(InfoPublishFile.from_scenario=="infopublish_attach_file", InfoPublishFile.foreign_key == info_id, InfoPublishFile.del_flag == '0')).all()
  275. data['attachs'] = [
  276. {
  277. "name": row.file_name,
  278. "url": row.storage_file_name
  279. }
  280. for row in rows
  281. ]
  282. # 审批附件
  283. rows = db.query(InfoPublishFile).filter(and_(InfoPublishFile.from_scenario=="infopublish_examine_attach_file", InfoPublishFile.foreign_key == info_id, InfoPublishFile.del_flag == '0')).all()
  284. data['examine_attachs'] = [
  285. {
  286. "name": row.file_name,
  287. "url": row.storage_file_name
  288. }
  289. for row in rows
  290. ]
  291. data["examines"] = []
  292. rows = db.query(InfoPublishExamine).filter(InfoPublishExamine.publish_id == info_id).filter(InfoPublishExamine.del_flag == '0').all()
  293. for row in rows:
  294. data["examines"].append({
  295. "examine_type": EXAMINE_TYPE_DICT[row.examine_type],
  296. "examine_sub_type": EXAMINE_SUB_TYPE_DICT[row.examine_sub_type],
  297. "content": row.content,
  298. "examine_time": get_datetime_str(row.examine_time),
  299. "user_id": row.user_id,
  300. "user_name": row.user_name,
  301. "nick_name": row.nick_name
  302. })
  303. return {
  304. "code": 200,
  305. "msg": "查询成功",
  306. "data": data
  307. }
  308. # 信息发布编辑保存
  309. @router.post('/edit')
  310. async def post_edit_info(
  311. request: Request,
  312. body = Depends(remove_xss_json),
  313. db: Session = Depends(get_db),
  314. user_id = Depends(valid_access_token)):
  315. try:
  316. id = body['id']
  317. remove_req_param(body, 'info_id')
  318. examines = body['examines']
  319. remove_req_param(body, 'examines')
  320. body['recorded_by'] = user_id
  321. db.query(InfoPublishBase).filter(InfoPublishBase.id == id).update(body)
  322. db.commit()
  323. return {
  324. "code": 200,
  325. "msg": "保存信息成功"
  326. }
  327. except Exception as e:
  328. # 处理异常
  329. traceback.print_exc()
  330. raise HTTPException(status_code=500, detail=str(e))
  331. # 信息发布提交审核
  332. @router.post('/examine')
  333. async def post_examine_info(
  334. request: Request,
  335. body = Depends(remove_xss_json),
  336. db: Session = Depends(get_db),
  337. user_id = Depends(valid_access_token)):
  338. user_row = db.query(SysUser).filter(SysUser.user_id == user_id).first()
  339. new_examine = InfoPublishExamine(
  340. pubish_id = body['info_id'],
  341. examine_type = body['examine_type'],
  342. examine_sub_type = body['examine_sub_type'],
  343. content = body['content'],
  344. examine_time = datetime.now(),
  345. user_id = user_id,
  346. user_name = user_row.user_name,
  347. nick_name = user_row.nick_name
  348. )
  349. db.add(new_examine)
  350. db.commit()
  351. return {
  352. "code": 200,
  353. "msg": "保存审批记录成功"
  354. }
  355. # 信息发布查看发送列表
  356. @router.get("/sent_list")
  357. async def get_sent_list(
  358. info_id: str = Query('', description='信息ID'),
  359. channel: str = Query('', description='渠道'),
  360. keywords: str = Query('', description='关键字'),
  361. sort_by: str = Query('', description='排序字段'),
  362. sort_order: str = Query("asc", description='排序方式'),
  363. page: int = Query(1, gt=0, description='页码'),
  364. page_size: int = Query(10, gt=0, description='pageSize'),
  365. db: Session = Depends(get_db)
  366. ):
  367. try:
  368. # 应用查询条件
  369. where = and_(InfoPublishResponses.publish_id == info_id)
  370. if channel != '':
  371. where = and_(where, InfoPublishResponses.publish_channel.like('%{}%'.format(channel)))
  372. # 计算总条目数
  373. q = db.query(func.count(InfoPublishResponses.id))
  374. q = q.filter(where)
  375. total = q.scalar()
  376. # 执行分页查询
  377. q = db.query(InfoPublishResponses)
  378. q = q.filter(where)
  379. rows = q.order_by(InfoPublishResponses.id.desc()).offset((page - 1) * page_size).limit(page_size).all()
  380. data = [
  381. {
  382. "user_id": row.user_id,
  383. "user_name": row.user_name,
  384. "nick_name": row.nick_name,
  385. "dept_name": row.dept_name,
  386. "sent_status": row.sent_status,
  387. "sent_time": get_datetime_str(row.sent_time),
  388. "response_type": row.response_type,
  389. "publish_channel": row.publish_channel,
  390. "yzy_account": row.yzy_account
  391. }
  392. for row in rows
  393. ]
  394. # 返回结果
  395. return {
  396. "code": 200,
  397. "msg": "查询成功",
  398. "data": data,
  399. "total": total
  400. }
  401. except Exception as e:
  402. # 处理异常
  403. traceback.print_exc()
  404. raise HTTPException(status_code=500, detail=str(e))
  405. # 列出可用模板
  406. @router.post("/template_list")
  407. def template_list(db: Session = Depends(get_db)):
  408. try:
  409. rows = db.query(InfoPublishTemplate).filter(InfoPublishTemplate.del_flag == '0').all()
  410. data = [
  411. {
  412. "id": row.id,
  413. "name": row.name,
  414. "content": row.content
  415. }
  416. for row in rows
  417. ]
  418. return {
  419. "code": 200,
  420. "msg": "查询成功",
  421. "data": data,
  422. "total": len(data)
  423. }
  424. except Exception as e:
  425. # 处理异常
  426. traceback.print_exc()
  427. raise HTTPException(status_code=500, detail=str(e))
  428. # 提交审批
  429. @router.post("/submit_examine")
  430. async def submit_examine(
  431. db: Session = Depends(get_db),
  432. body = Depends(remove_xss_json),
  433. user_id = Depends(valid_access_token)
  434. ):
  435. try:
  436. user_row = db.query(SysUser).filter(SysUser.user_id == user_id).first()
  437. info_id = body['info_id']
  438. examine_type = body['examine_type']
  439. content = body['content']
  440. # 审批通过
  441. if examine_type == 'approved':
  442. new_examine = InfoPublishExamine(
  443. publish_id = info_id,
  444. examine_type = 20,
  445. examine_sub_type = 21,
  446. content = content,
  447. examine_time = datetime.now(),
  448. user_id = user_id,
  449. user_name = user_row.user_name,
  450. nick_name = user_row.nick_name
  451. )
  452. db.add(new_examine)
  453. db.commit()
  454. db.query(InfoPublishBase).filter(InfoPublishBase.id == info_id).update({"publish_status": 3, "examine_status": 2})
  455. db.commit()
  456. # 审批不通过
  457. elif examine_type == 'rejected':
  458. new_examine = InfoPublishExamine(
  459. publish_id = info_id,
  460. examine_type = 20,
  461. examine_sub_type = 22,
  462. content = content,
  463. examine_time = datetime.now(),
  464. user_id = user_id,
  465. user_name = user_row.user_name,
  466. nick_name = user_row.nick_name
  467. )
  468. db.add(new_examine)
  469. db.commit()
  470. db.query(InfoPublishBase).filter(InfoPublishBase.id == info_id).update({"publish_status": 0, "examine_status": 0})
  471. db.commit()
  472. return {
  473. "code": 200,
  474. "msg": "审批成功"
  475. }
  476. except Exception as e:
  477. # 处理异常
  478. traceback.print_exc()
  479. raise HTTPException(status_code=500, detail=str(e))