__init__.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. from fastapi import FastAPI, HTTPException, Depends, APIRouter,Query,Body
  2. from sqlalchemy.engine.reflection import Inspector
  3. from pydantic import BaseModel,Extra
  4. from datetime import datetime
  5. from typing import List, Optional,Any,Dict
  6. from sqlalchemy import create_engine, Column, Integer, String, Boolean, MetaData, Table, inspect, exists,or_,text,insert
  7. from sqlalchemy.orm import Session
  8. from pypinyin import lazy_pinyin, Style
  9. from database import get_db
  10. from models import *
  11. import random
  12. router = APIRouter()
  13. metadata = MetaData()
  14. class ReportField(BaseModel):
  15. name: str
  16. class ReportCreate(BaseModel):
  17. table_name: str
  18. start_time: str
  19. end_time: str
  20. status: str
  21. issued_status: str
  22. period_type: str
  23. creator_name: str
  24. creator_id: int
  25. creator_phone:str
  26. # num_reporters:int
  27. field_names: List[str] # 用户只传递字段名称
  28. user_ids: List[int]
  29. def get_next_event_id(db: Session):
  30. while True:
  31. random_10_digit_number = random.randint(1000000000, 9999999999)
  32. reportId = 'report' + str(random_10_digit_number)
  33. it_exists = db.query(
  34. exists().where(ReportManagement.report_id == reportId)
  35. ).scalar()
  36. if it_exists == False:
  37. return reportId
  38. # 函数用于将中文转换为拼音首字母缩写
  39. def to_first_letter(chinese_str: str) -> str:
  40. return ''.join([p[0][0] for p in lazy_pinyin(chinese_str, style=Style.FIRST_LETTER)]).lower()
  41. # class ReportQuery(BaseModel):
  42. # report_id: str
  43. class TableStructure(BaseModel):
  44. column_name: str
  45. comment: str
  46. #查看详情
  47. @router.get("/report_structure/{report_id}")
  48. async def get_report_structure(
  49. report_id: str,
  50. db: Session = Depends(get_db)
  51. ):
  52. # 查询 ReportManagement 表以获取 data_table_name
  53. report = db.query(ReportManagement).filter(ReportManagement.report_id == report_id).first()
  54. if not report:
  55. raise HTTPException(status_code=404, detail="Report not found")
  56. data_table_name = report.data_table_name
  57. # 查询对应表的表结构
  58. table_structure_query = db.execute(
  59. text("""
  60. SELECT COLUMN_NAME, COLUMN_COMMENT
  61. FROM INFORMATION_SCHEMA.COLUMNS
  62. WHERE TABLE_NAME = :table_name AND TABLE_SCHEMA = (SELECT DATABASE())
  63. """),
  64. {"table_name": data_table_name}
  65. )
  66. table_structures = []
  67. for row in table_structure_query.fetchall():
  68. if row[0] not in ['collect_status','create_id','id','user_id']:
  69. table_structures.append(TableStructure(column_name=row[0], comment=row[1]))
  70. # # 查询 user_id 去重后的数量
  71. # distinct_user_count_query = db.execute(
  72. # text("""
  73. # SELECT COUNT(DISTINCT user_id) AS distinct_user_count
  74. # FROM {}
  75. # """.format(data_table_name))
  76. # )
  77. # num_reported = distinct_user_count_query.scalar()
  78. # num_unreported = report.num_reporters - num_reported
  79. # 构造返回结果,包括 ReportManagement 表中的记录和其他相关信息
  80. # 计算去重用户数量
  81. distinct_users = db.query(FormSubmission.user_id).filter(
  82. FormSubmission.report_id == report_id).distinct().count()
  83. # 计算已填报数量(填报结果为1)
  84. num_reported = db.query(FormSubmission).filter(FormSubmission.report_id == report_id,
  85. FormSubmission.submission_status == 1).count()
  86. # 计算未填报数量(填报结果为0)
  87. num_unreported = db.query(FormSubmission).filter(FormSubmission.report_id == report_id,
  88. FormSubmission.submission_status == 0).count()
  89. print("xx")
  90. print(distinct_users,num_reported,num_unreported)
  91. result = {
  92. "code": 200,
  93. 'msg': '查询成功',
  94. 'report_info': {
  95. "id": report.id,
  96. "report_id": report.report_id,
  97. "table_name": report.table_name,
  98. "data_table_name": report.data_table_name,
  99. "start_time": report.start_time,
  100. "end_time": report.end_time,
  101. "status": report.status,
  102. "issued_status": report.issued_status,
  103. "period_type": report.period_type,
  104. "creator_name": report.creator_name,
  105. "num_reporters": distinct_users,
  106. "creator_id": report.creator_id,
  107. "created_at": report.created_at,
  108. "updated_at": report.updated_at,
  109. "num_reported":num_reported,
  110. "num_unreported":num_unreported
  111. },
  112. 'table_structure': table_structures
  113. }
  114. return result
  115. # 动态创建表
  116. def create_dynamic_table(table_name: str, field_names: List[str], db: Session):
  117. inspector = inspect(db.bind)
  118. # 检查表是否已存在
  119. if inspector.has_table(table_name):
  120. raise HTTPException(status_code=400, detail="Table already exists")
  121. table = Table(table_name, metadata,
  122. Column('id', Integer, primary_key=True),
  123. Column('user_id', Integer),
  124. Column('create_id', Integer),
  125. Column('collect_status', Boolean)
  126. )
  127. existing_columns = set()
  128. for field_name in field_names:
  129. column_name = to_first_letter(field_name)
  130. # 如果列名已存在,则添加一个唯一的后缀
  131. unique_column_name = column_name
  132. suffix = 1
  133. while unique_column_name in existing_columns:
  134. unique_column_name = f"{column_name}_{suffix}"
  135. suffix += 1
  136. existing_columns.add(unique_column_name)
  137. table.append_column(Column(unique_column_name, String(255), comment=field_name))
  138. # 创建表
  139. metadata.create_all(bind=db.bind)
  140. # 新建填报和创建新表的接口
  141. @router.post("/report/")
  142. def create_report_and_table(report: ReportCreate, db: Session = Depends(get_db)):
  143. try:
  144. # 获取当前时间并格式化为 YYYYMMDDHHMMSS
  145. current_time_str = datetime.now().strftime("%Y%m%d%H%M%S")
  146. # 动态生成 data_table_name
  147. table_name_pinyin=''
  148. for i in range(len(lazy_pinyin(report.table_name, style=Style.FIRST_LETTER))):
  149. table_name_pinyin += ''.join(lazy_pinyin(report.table_name, style=Style.FIRST_LETTER)[i]).lower()
  150. data_table_name = f"{table_name_pinyin}_{current_time_str}"
  151. # 动态创建新表
  152. create_dynamic_table(data_table_name, report.field_names, db)
  153. # 登记填报管理
  154. new_report = ReportManagement(
  155. report_id=get_next_event_id(db),
  156. table_name=report.table_name,
  157. data_table_name=data_table_name,
  158. start_time=datetime.now(),
  159. end_time=datetime.now(),
  160. status=report.status,
  161. issued_status=report.issued_status,
  162. collection_status=0,#未收取
  163. period_type=report.period_type,
  164. creator_name=report.creator_name,
  165. creator_id=report.creator_id,
  166. creator_phone=report.creator_phone,
  167. num_reporters = len(report.user_ids)
  168. )
  169. db.add(new_report)
  170. db.commit()
  171. db.refresh(new_report)
  172. # 为每个用户创建填报记录
  173. for user_id in report.user_ids:
  174. submission = FormSubmission(
  175. report_id=new_report.report_id ,
  176. user_id=user_id,
  177. submission_status=0 # 默认状态为未填报
  178. )
  179. db.add(submission)
  180. db.commit()
  181. return {
  182. "code": 200,
  183. "msg":"创建成功"
  184. }
  185. except Exception as e:
  186. raise HTTPException(status_code=400, detail=str(e))
  187. class ReportQuery(BaseModel):
  188. creator_id: str # 创建者ID,必须提供
  189. table_name: Optional[str] = None
  190. status: Optional[List[int]] = None
  191. start_time: Optional[datetime] = None
  192. end_time: Optional[datetime] = None
  193. issued_status: Optional[List[int]] = None
  194. page_num: int = 1
  195. page_size: int = 10
  196. @router.post("/select")
  197. @router.get("/select")
  198. async def select_report(
  199. db: Session = Depends(get_db),
  200. query: ReportQuery = Depends()
  201. ):
  202. # 检查 creator_id 是否提供
  203. if not query.creator_id:
  204. raise HTTPException(status_code=400, detail="创建者ID是必填项")
  205. data_query = db.query(ReportManagement).filter(ReportManagement.creator_id == query.creator_id)
  206. # 过滤条件
  207. if query.table_name:
  208. data_query = data_query.filter(ReportManagement.table_name.ilike(f"%{query.table_name}%"))
  209. if query.start_time and query.end_time:
  210. data_query = data_query.filter(ReportManagement.start_time >= query.start_time,
  211. ReportManagement.end_time <= query.end_time)
  212. if query.status:
  213. data_query = data_query.filter(ReportManagement.status.in_(query.status))
  214. if query.issued_status:
  215. data_query = data_query.filter(ReportManagement.issued_status.in_(query.issued_status))
  216. # 计算总数
  217. total_count = data_query.count()
  218. # 分页查询
  219. offset = (query.page_num - 1) * query.page_size
  220. data = data_query.offset(offset).limit(query.page_size).all()
  221. # 构造结果
  222. result_items = []
  223. for item in data:
  224. result_item = {
  225. "id": item.id,
  226. "report_id": item.report_id,
  227. "table_name": item.table_name,
  228. "data_table_name": item.data_table_name,
  229. "start_time": item.start_time,
  230. "end_time": item.end_time,
  231. "status": item.status,
  232. "issued_status": item.issued_status,
  233. "period_type": item.period_type,
  234. "creator_name": item.creator_name,
  235. "creator_id": item.creator_id,
  236. "created_at": item.created_at,
  237. "creator_phone": item.creator_phone,
  238. "updated_at": item.updated_at,
  239. "num_reporters": item.num_reporters
  240. }
  241. result_items.append(result_item)
  242. result = {
  243. "code": 200,
  244. 'msg': '查询成功',
  245. 'pages': (total_count + query.page_size - 1) // query.page_size,
  246. 'total': total_count,
  247. "currentPage": query.page_num,
  248. "pageSize": query.page_size,
  249. 'data': result_items
  250. }
  251. return result
  252. class ReportUpdate(BaseModel):
  253. table_name: str = None
  254. status: int = None
  255. issued_status: int = None
  256. period_type: str = None
  257. end_time: str = None
  258. comments: dict = None # 字典,键为字段名,值为新的备注
  259. creator_id: str = None
  260. #修改
  261. @router.put("/report/{report_id}/")
  262. async def update_report(
  263. report_id: str,
  264. update_data: ReportUpdate,
  265. db: Session = Depends(get_db)
  266. ):
  267. # 查询要修改的记录
  268. report = db.query(ReportManagement).filter(ReportManagement.report_id == report_id).first()
  269. if not report:
  270. raise HTTPException(status_code=404, detail="Report not found")
  271. # 验证请求者ID
  272. if report.creator_id != update_data.creator_id:
  273. raise HTTPException(status_code=403, detail="没有权限更新此报告")
  274. # 更新字段
  275. if update_data.table_name:
  276. report.table_name = update_data.table_name
  277. if update_data.status is not None:
  278. report.status = update_data.status
  279. if update_data.issued_status is not None:
  280. report.issued_status = update_data.issued_status
  281. if update_data.period_type:
  282. report.period_type = update_data.period_type
  283. if update_data.end_time:
  284. report.end_time = datetime.fromisoformat(update_data.end_time)
  285. # 更新字段备注
  286. if update_data.comments:
  287. for column_name, comment in update_data.comments.items():
  288. db.execute(
  289. text(f"""
  290. ALTER TABLE {report.data_table_name} CHANGE {column_name} {column_name} VARCHAR(255) COMMENT :comment
  291. """),
  292. {"comment": comment}
  293. )
  294. db.commit()
  295. db.refresh(report)
  296. return {
  297. "code":200,
  298. "msg":"操作成功"
  299. }
  300. class TaskQuery(BaseModel):
  301. user_id: str
  302. submission_status: Optional[List[int]] = None
  303. table_name: Optional[str] = None
  304. @router.post("/my_filling")
  305. @router.get("/my_filling")
  306. async def get_user_tasks(
  307. db: Session = Depends(get_db),
  308. query: TaskQuery = Body(...)
  309. ):
  310. # 检查用户ID是否提供
  311. if not query.user_id:
  312. raise HTTPException(status_code=400, detail="用户ID是必填项")
  313. # 查询用户的所有任务信息
  314. user_tasks = db.query(ReportManagement, FormSubmission).join(
  315. FormSubmission, ReportManagement.report_id == FormSubmission.report_id
  316. ).filter(
  317. FormSubmission.user_id == query.user_id
  318. )
  319. # 如果提供了填报结果列表,则过滤结果
  320. if query.submission_status:
  321. user_tasks = user_tasks.filter(FormSubmission.submission_status.in_(query.submission_status))
  322. if query.table_name:
  323. user_tasks = user_tasks.filter(ReportManagement.table_name.ilike(f'%{query.table_name}%'))
  324. # 执行查询
  325. tasks = user_tasks.all()
  326. # 构造返回结果
  327. result_items = []
  328. for report, submission in tasks:
  329. result_item = {
  330. "user_id":query.user_id,
  331. "table_name": report.table_name,
  332. "report_id": report.report_id,
  333. "submission_status": submission.submission_status,
  334. "start_time": report.start_time,
  335. "end_time": report.end_time,
  336. }
  337. result_items.append(result_item)
  338. return {
  339. "code":200,
  340. "msg":"查询成功",
  341. "data": result_items
  342. }
  343. @router.get("/report_fields")
  344. @router.post("/report_fields")
  345. async def get_report_fields(
  346. db: Session = Depends(get_db),
  347. user_id: str = Query(None, description="用户ID"),
  348. report_id: str = Query(None, description="填报ID")
  349. ):
  350. # 检查用户ID和填报ID是否提供
  351. if not user_id or not report_id:
  352. raise HTTPException(status_code=400, detail="用户ID和填报ID是必填项")
  353. # 获取对应填报ID的数据表名称
  354. report = db.query(ReportManagement).filter(ReportManagement.report_id == report_id).first()
  355. if not report:
  356. raise HTTPException(status_code=404, detail="未找到对应的填报ID")
  357. data_table_name = report.data_table_name
  358. if not data_table_name:
  359. raise HTTPException(status_code=404, detail="未找到对应的数据表名称")
  360. # 检查用户是否有权限访问填报数据
  361. submission = db.query(FormSubmission).filter(
  362. FormSubmission.report_id == report_id,
  363. FormSubmission.user_id == user_id
  364. ).first()
  365. if not submission:
  366. raise HTTPException(status_code=403, detail="没有权限访问这个填报数据")
  367. # 使用SQLAlchemy的inspect功能来获取表的字段信息
  368. inspector = inspect(db.bind)
  369. columns = inspector.get_columns(data_table_name)
  370. # 构造返回结果
  371. result_fields = []
  372. for column in columns:
  373. if column['name'] not in ['collect_status', 'create_id', 'id', 'user_id']:
  374. result_field = {
  375. "field_name": column['name'],
  376. "field_comment": column.get('comment', '无注释')
  377. }
  378. result_fields.append(result_field)
  379. # 返回用户ID、填报ID和字段信息
  380. return {
  381. "code":200,
  382. "msg":"查询成功",
  383. "user_id": user_id,
  384. "report_id": report_id,
  385. "fields": result_fields
  386. }
  387. class DataEntry(BaseModel):
  388. data: List[Dict[str, Any]] # 数据列表,每个元素是一个字典,包含字段名和值
  389. class DataItem(BaseModel):
  390. pass # 用于动态接收键值对
  391. class SubmitData(BaseModel):
  392. user_id: int
  393. report_id: str
  394. data: List[Dict[str, str]] # 数据列表,每个元素是一个字典,包含字段名和值
  395. class Config:
  396. arbitrary_types_allowed = True
  397. @router.post("/submit_data")
  398. async def submit_data(
  399. db: Session = Depends(get_db),
  400. submit_data: SubmitData = Body(...)
  401. ):
  402. # 检查用户ID和填报ID是否提供
  403. if not submit_data.user_id or not submit_data.report_id:
  404. raise HTTPException(status_code=400, detail="用户ID和填报ID是必填项")
  405. # 获取对应填报ID的数据表名称
  406. report = db.query(ReportManagement).filter(ReportManagement.report_id == submit_data.report_id).first()
  407. if not report:
  408. raise HTTPException(status_code=404, detail="未找到对应的填报ID")
  409. data_table_name = report.data_table_name
  410. if not data_table_name:
  411. raise HTTPException(status_code=404, detail="未找到对应的数据表名称")
  412. # 检查用户是否有权限填报
  413. submission = db.query(FormSubmission).filter(
  414. FormSubmission.report_id == submit_data.report_id,
  415. FormSubmission.user_id == str(submit_data.user_id) # 确保user_id是字符串类型
  416. ).first()
  417. if not submission:
  418. raise HTTPException(status_code=403, detail="用户没有填报权限")
  419. # print(report.creator_id,submit_data.user_id)
  420. # 将数据写入数据库
  421. for item in submit_data.data:
  422. # 构造插入SQL语句
  423. columns = ', '.join(list(item.keys()) + ['create_id', 'user_id', 'collect_status'])
  424. values = ', '.join(
  425. [f":{k}" for k in item.keys()] + [f"'{report.creator_id}'", f"'{submit_data.user_id}'", '1'])
  426. sql = f"INSERT INTO {data_table_name} ({columns}) VALUES ({values})"
  427. print(sql)
  428. # 执行插入操作
  429. db.execute(text(sql), item)
  430. submission.submission_status = 1
  431. db.add(submission)
  432. # 提交事务
  433. db.commit()
  434. return {
  435. "code":200,
  436. "msg": "数据提交成功"
  437. }
  438. class SubmissionQuery(BaseModel):
  439. user_id: int # 用户ID,必须是整数
  440. report_id: str # 填报ID,必须是字符串
  441. @router.post("/submission_status")
  442. async def get_submission_status(
  443. db: Session = Depends(get_db),
  444. query: SubmissionQuery = Body(...)
  445. ):
  446. # 检查用户ID和填报ID是否提供
  447. if not query.user_id or not query.report_id:
  448. raise HTTPException(status_code=400, detail="用户ID和填报ID是必填项")
  449. # 获取对应填报ID的数据表名称
  450. report = db.query(ReportManagement).filter(ReportManagement.report_id == query.report_id).first()
  451. if not report:
  452. raise HTTPException(status_code=404, detail="未找到对应的填报ID")
  453. data_table_name = report.data_table_name
  454. if not data_table_name:
  455. raise HTTPException(status_code=404, detail="未找到对应的数据表名称")
  456. # 获取填报情况
  457. submission = db.query(FormSubmission).filter(
  458. FormSubmission.report_id == query.report_id,
  459. FormSubmission.user_id == str(query.user_id) # 确保user_id是字符串类型
  460. ).first()
  461. if not submission:
  462. raise HTTPException(status_code=404, detail="未找到对应的填报情况")
  463. start_time = report.start_time
  464. end_time = report.end_time
  465. print(start_time,end_time)
  466. start_time_str = start_time.strftime('%Y-%m-%d %H:%M:%S')
  467. end_time_str = end_time.strftime('%Y-%m-%d %H:%M:%S')
  468. # 使用SQLAlchemy的inspect功能来获取表的列信息
  469. inspector = Inspector.from_engine(db.bind)
  470. columns = inspector.get_columns(data_table_name)
  471. # 提取列名和列注释
  472. column_names = [column['name'] for column in columns]
  473. column_comments = {column['name']: column['comment'] for column in columns if 'comment' in column}
  474. # 构造返回结果
  475. result_items = []
  476. excluded_columns = ['id', 'user_id', 'create_id', 'collect_status']
  477. # 构建查询SQL
  478. query_sql = text(f"""
  479. SELECT * FROM {data_table_name} WHERE user_id = :user_id
  480. """)
  481. result = db.execute(query_sql, {"user_id": query.user_id})
  482. rows = result.fetchall()
  483. # 添加字段名和字段注释作为第一行
  484. first_row = {column: column_comments.get(column, '') for column in column_names if
  485. column not in excluded_columns}
  486. result_items.append(first_row)
  487. for row in rows:
  488. # 过滤掉不需要的列
  489. filtered_row = {column: row[idx] for idx, column in enumerate(column_names) if
  490. column not in excluded_columns}
  491. result_items.append(filtered_row)
  492. result = {
  493. "code": 200,
  494. 'msg': '查询成功',
  495. 'start_time':start_time_str,
  496. "end_time":end_time_str,
  497. "data": result_items}
  498. return result
  499. # 辅助函数:根据字段备注获取表中所有匹配字段名
  500. def get_columns_with_comment_like(
  501. inspector: Inspector, table_name: str, comment_like: str
  502. ) -> List[str]:
  503. columns = inspector.get_columns(table_name)
  504. matching_columns = [column['name'] for column in columns if column.get('comment') and comment_like in column['comment']]
  505. return matching_columns
  506. # 辅助函数:检查是否有字段备注匹配
  507. def has_matching_column_comments(
  508. inspector: Inspector, table_name: str, comment_like: str
  509. ) -> bool:
  510. return bool(get_columns_with_comment_like(inspector, table_name, comment_like))
  511. @router.post("/reports_by_creator/")
  512. async def get_reports_by_creator(
  513. creator_id: str, # 精确匹配的必选参数
  514. field_comment: Optional[str] = Query(None, description="Optional comment of the field to match"),
  515. db: Session = Depends(get_db)
  516. ):
  517. # 获取数据库Inspector
  518. inspector: Inspector = inspect(db.bind)
  519. # 查询 ReportManagement 表以获取所有相关的记录
  520. reports = db.query(ReportManagement).filter(ReportManagement.creator_id == creator_id).all()
  521. # 存储结果
  522. results = []
  523. for report in reports:
  524. # 检查是否存在 data_table_name
  525. if not report.data_table_name:
  526. continue # 如果没有 data_table_name,跳过这个 report
  527. # 检查是否有字段备注匹配 field_comment
  528. if field_comment and not has_matching_column_comments(inspector, report.data_table_name, field_comment):
  529. continue # 如果没有匹配的字段备注,跳过这个 report
  530. # 如果匹配成功,添加到结果中
  531. collection_time_str = report.collection_time.isoformat().replace('T', ' ') if report.collection_time else None
  532. results.append({
  533. "table_name": report.table_name,
  534. "collection_status": report.collection_status,
  535. "collection_time": collection_time_str,
  536. "report_id": report.report_id
  537. })
  538. # 如果没有找到任何记录,抛出404异常
  539. if not results:
  540. raise HTTPException(status_code=404, detail="没有找到与该创建人ID相关的记录")
  541. return {"data": results}
  542. @router.put("/update_collection_status/")
  543. async def update_collection_status(
  544. creator_id: str,
  545. report_id: str,
  546. new_status: int = Query(..., description="New collection status, must be 0, 1, or 2"),
  547. db: Session = Depends(get_db)
  548. ):
  549. # 检查 new_status 是否为允许的值之一
  550. if new_status not in (0, 1, 2):
  551. raise HTTPException(status_code=400, detail="Invalid collection status value")
  552. # 查询 ReportManagement 表以获取对应记录
  553. report = db.query(ReportManagement).filter(
  554. ReportManagement.creator_id == creator_id,
  555. ReportManagement.report_id == report_id
  556. ).first()
  557. # 如果没有找到记录,返回404
  558. if not report:
  559. raise HTTPException(status_code=404, detail="Report not found")
  560. # 更新 collection_status
  561. report.collection_status = new_status
  562. db.add(report)
  563. db.commit()
  564. db.refresh(report)
  565. return {
  566. "code":200,
  567. "msg": "更新成功",
  568. "new_status": new_status
  569. }
  570. class ReportQuery(BaseModel):
  571. creator_id: str # 创建人ID,必须是字符串
  572. report_id: str # 填报ID,必须是字符串
  573. @router.get("/dataArchiveDetails/")
  574. async def get_records_by_creator_and_report(
  575. query: ReportQuery = Depends(),
  576. db: Session = Depends(get_db)
  577. ):
  578. # 查询 ReportManagement 表以获取对应记录
  579. report = db.query(ReportManagement).filter(
  580. ReportManagement.creator_id == query.creator_id,
  581. ReportManagement.report_id == query.report_id
  582. ).first()
  583. # 如果没有找到记录,返回404
  584. if not report:
  585. raise HTTPException(status_code=404, detail="Report not found")
  586. # 如果没有 data_table_name,返回404
  587. if not report.data_table_name:
  588. raise HTTPException(status_code=404, detail="Data table name not found")
  589. # 查询工单表所有信息,并关联用户表匹配到用户名字
  590. query_sql = text(f"""
  591. SELECT w.*, u.user_name
  592. FROM {report.data_table_name} w
  593. LEFT JOIN sys_user u ON w.user_id = u.user_id
  594. """)
  595. result = db.execute(query_sql)
  596. rows = result.fetchall()
  597. # 使用SQLAlchemy的inspect功能来获取表的列信息
  598. inspector = inspect(db.bind)
  599. columns = inspector.get_columns(report.data_table_name)
  600. # 提取列名和列注释
  601. column_names = [column['name'] for column in columns]
  602. column_comments = {column['name']: column['comment'] for column in columns if 'comment' in column}
  603. # 构造返回结果
  604. results = []
  605. excluded_columns = ['id', 'user_id', 'create_id', 'collect_status']
  606. # 添加字段名和字段注释作为第一行
  607. first_row = {column: column_comments.get(column, '') for column in column_names if column not in excluded_columns}
  608. first_row['user_name'] = column_comments.get('user_name', '用户昵称') # 添加用户昵称的注释
  609. results.append(first_row)
  610. for row in rows:
  611. # 过滤掉不需要的列,并添加到结果中
  612. filtered_row = {column: row[idx] for idx, column in enumerate(column_names) if column not in excluded_columns}
  613. filtered_row['user_name'] = row[-1] # 添加用户昵称
  614. results.append(filtered_row)
  615. # 获取报告的开始和结束时间,并格式化为字符串
  616. start_time_str = report.start_time.strftime('%Y-%m-%d %H:%M:%S') if report.start_time else None
  617. end_time_str = report.end_time.strftime('%Y-%m-%d %H:%M:%S') if report.end_time else None
  618. return {
  619. "code": 200,
  620. 'msg': '查询成功',
  621. 'start_time': start_time_str,
  622. "end_time": end_time_str,
  623. "data": results
  624. }