back.py 19 KB

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