classification.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. from fastapi import APIRouter, Request, Depends, Query, HTTPException, status,WebSocket,WebSocketDisconnect
  4. from common.security import valid_access_token,valid_websocket_token
  5. from fastapi.responses import JSONResponse
  6. from sqlalchemy.orm import Session
  7. from sqlalchemy.sql import func
  8. from common.auth_user import *
  9. from sqlalchemy import text
  10. from pydantic import BaseModel
  11. from common.BigDataCenterAPI import *
  12. from database import get_db
  13. from typing import List
  14. from models import *
  15. from utils import *
  16. from utils.spatial import *
  17. from utils.ry_system_util import *
  18. from common.websocketManager import *
  19. from openpyxl import load_workbook
  20. from PIL import Image
  21. import io
  22. import json
  23. import xlrd,os
  24. import traceback
  25. router = APIRouter()
  26. def classification_id_get_classification_info(db,id):
  27. query = db.query(TpPatternClassification)
  28. query = query.filter_by(classification_id = id,del_flag = '0')
  29. return query.first()
  30. def template_id_get_classification_list(db,id):
  31. query = db.query(TpPatternClassification)
  32. query = query.filter_by(template_id = id,del_flag = '0')
  33. query = query.order_by(TpPatternClassification.order_num.asc())
  34. return query.all()
  35. def template_id_get_template_info(db,id):
  36. query = db.query(TpPatternTemplate)
  37. query = query.filter_by(template_id = id,del_flag = '0')
  38. return query.first()
  39. def read_save_excel_img(file_path):
  40. wb = load_workbook(file_path)
  41. ws = wb.active
  42. data={}
  43. for drawing in ws._images:
  44. img_bytes = drawing._data()
  45. anchor = drawing.anchor
  46. # 锚点给出的是“起始行列”和“终止行列”
  47. col0, row0 = anchor._from.col, anchor._from.row
  48. img = Image.open(io.BytesIO(img_bytes))
  49. w, h = img.size # 像素宽高
  50. # print(f'第1张图片:宽={w}px, 高={h}px')
  51. name = new_guid()
  52. img.save(f'{name}.png')
  53. data[f'{col0}-{row0}']={"size":[h, w],"image":f'{name}.png'}
  54. return data
  55. @router.post('/createImport')
  56. async def create_contact(
  57. request: Request,
  58. db: Session = Depends(get_db),
  59. body=Depends(remove_xss_json),
  60. auth_user: AuthUser = Depends(find_auth_user),
  61. user_id=Depends(valid_access_token)
  62. ):
  63. try:
  64. # 提取请求数据
  65. filename = body['filename']
  66. # file_name_desc = body['file_name_desc']
  67. template_id = body['template_id']
  68. if len(filename) == 0:
  69. raise Exception()
  70. file_path = f'/data/upload/mergefile/uploads/{filename}'
  71. # 检查文件是否存在
  72. if not os.path.isfile(file_path):
  73. return JSONResponse(status_code=404, content={
  74. 'errcode': 404,
  75. 'errmsg': f'{filename}不存在'
  76. })
  77. msg = '成功'
  78. code =200
  79. try:
  80. book = xlrd.open_workbook(file_path)
  81. sheet = book.sheet_by_index(0)
  82. img_list = read_save_excel_img(file_path)
  83. if sheet.nrows-1 != len(img_list):
  84. msg = f'\n文件图片缺失,请核实图片个数是否为 {sheet.nrows-1}'
  85. code = 500
  86. return JSONResponse(status_code=code, content={
  87. "code": code,
  88. "msg": msg,
  89. "data": None
  90. })
  91. except Exception as e:
  92. traceback.print_exc()
  93. msg = f'\n文件打开失败,请核实文件格式为xlsx/xlx>{str(e)}'
  94. code = 500
  95. return JSONResponse(status_code=code, content={
  96. "code": code,
  97. "msg": msg,
  98. "data": None
  99. })
  100. data = []
  101. import_status = True
  102. for row in range(1, sheet.nrows):
  103. name = sheet.cell(row, 0).value
  104. if name == '' or name==0:
  105. import_status = False
  106. msg = f'\n行<{row + 1}>分类名称不能为空<{name}>'
  107. code = 500
  108. value = sheet.cell(row, 1).value
  109. if value == '':
  110. import_status = False
  111. msg = f'\n行<{row + 1}>分类值不能为空<{value}>'
  112. code = 500
  113. try:
  114. img_data=img_list[f'2-{row}']
  115. except:
  116. import_status = False
  117. msg = f'\n行<{row + 1}>图片不能为空<{value}>'
  118. code = 500
  119. return JSONResponse(status_code=code, content={
  120. "code": code,
  121. "msg": msg,
  122. "data": None
  123. })
  124. new_classification = TpPatternClassification(
  125. classification_id=new_guid(),
  126. template_id=template_id,
  127. name=body['name'],
  128. value=body['value'],
  129. order_num=0,
  130. visible='1',
  131. image=img_data['image'],
  132. icon=body['value'],
  133. size=img_data['size'],
  134. create_by=user_id
  135. )
  136. data.append(new_classification)
  137. if import_status:
  138. db.add_all(data)
  139. db.commit()
  140. except Exception as e:
  141. traceback.print_exc()
  142. # 处理异常
  143. db.rollback()
  144. code = 500
  145. msg = str(e)
  146. return JSONResponse(status_code=code, content={
  147. "code": code,
  148. "msg": msg,
  149. "data": None
  150. })
  151. @router.post("/create")
  152. async def create_pattern(
  153. user_id=Depends(valid_access_token),
  154. body = Depends(remove_xss_json),
  155. db: Session = Depends(get_db)
  156. ):
  157. try:
  158. if 'order_num' in body:
  159. order_num=body['order_num']
  160. else:
  161. info = db.query(func.max(TpPatternClassification.order_num).label('max_value')).filter_by(template_id=body['template_id']).first()
  162. if info.max_value:
  163. order_num=info.max_value+1
  164. else:
  165. order_num=1
  166. if 'visible'in body:
  167. visible=body['visible']
  168. else:
  169. visible='1'
  170. new_classification = TpPatternClassification(
  171. classification_id=new_guid(),
  172. template_id=body['template_id'],
  173. name=body['name'],
  174. value=body['value'],
  175. order_num = order_num,
  176. visible=visible,
  177. image=body['image'],
  178. icon=body['icon'],
  179. size=body['size'],
  180. create_by = user_id
  181. )
  182. db.add(new_classification)
  183. db.commit()
  184. return {"code": 200, "msg": "创建成功", "data": None}
  185. except Exception as e:
  186. traceback.print_exc()
  187. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  188. @router.put("/update/{id}")
  189. async def update_classification(
  190. id :str ,
  191. user_id=Depends(valid_access_token),
  192. body=Depends(remove_xss_json),
  193. db: Session = Depends(get_db)
  194. ):
  195. try:
  196. update_classification = classification_id_get_classification_info(db,id)
  197. if not update_classification:
  198. return JSONResponse(status_code=404,content={"code":404,"msg":"classification not found"})
  199. update_classification.template_id = body['template_id']
  200. update_classification.name = body['name']
  201. update_classification.value=body['value']
  202. update_classification.order_num=body['order_num']
  203. update_classification.visible=body['visible']
  204. update_classification.image=body['image']
  205. update_classification.icon=body['icon']
  206. update_classification.size=body['size']
  207. update_classification.update_by = user_id
  208. db.commit()
  209. return {"code": 200, "msg": "更新成功"}
  210. except Exception as e:
  211. traceback.print_exc()
  212. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  213. @router.get("/info/{id}")
  214. async def get_pattern_info(
  215. id: str,
  216. db: Session = Depends(get_db)
  217. ):
  218. try:
  219. info = classification_id_get_classification_info(db,id)
  220. if not info:
  221. return JSONResponse(status_code=404,content={"code":404,"msg":"classification not found"})
  222. template_info = template_id_get_template_info(db,info.template_id)
  223. data = {"classification_id": info.classification_id,
  224. "template_id": info.template_id,
  225. "template_name":template_info.name,
  226. "name": info.name,
  227. "value": info.value,
  228. "order_num": info.order_num,
  229. "visible": info.visible,
  230. "image": info.image,
  231. "icon": info.icon,
  232. "size": info.size,
  233. "create_time": info.create_time}
  234. return {"code": 200, "msg": "获取成功", "data": data}
  235. except Exception as e:
  236. traceback.print_exc()
  237. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  238. @router.get("/list")
  239. async def get_pattern_list(
  240. name: str = Query(None, description='名称'),
  241. page: int = Query(1, gt=0, description='页码'),
  242. pageSize: int = Query(None, gt=0, description='每页条目数量'),
  243. db: Session = Depends(get_db)
  244. ):
  245. try:
  246. query = db.query(TpPatternClassification)
  247. query = query.filter_by(del_flag='0')
  248. if name:
  249. query = query.filter(TpPatternClassification.name.like(f'%{name}%'))
  250. total_items = query.count()
  251. # 排序
  252. if pageSize is None:
  253. pageSize=total_items
  254. query = query.order_by(TpPatternClassification.order_num.asc())
  255. # 执行分页查询
  256. lists = query.offset((page - 1) * pageSize).limit(pageSize).all()
  257. data = [ ]
  258. for info in lists:
  259. template_info = template_id_get_template_info(db, info.template_id)
  260. data.append({"classification_id": info.classification_id,
  261. "template_id": info.template_id,
  262. "template_name":template_info.name,
  263. "name": info.name,
  264. "value": info.value,
  265. "order_num": info.order_num,
  266. "visible": info.visible,
  267. "image": info.image,
  268. "icon": info.icon,
  269. "size": info.size,
  270. "create_time": info.create_time})
  271. return {"code": 200, "msg": "查询成功", "data": data,
  272. "total": total_items,
  273. "page": page,
  274. "pageSize": pageSize,
  275. "totalPages": (total_items + pageSize - 1) // pageSize
  276. }
  277. except Exception as e:
  278. traceback.print_exc()
  279. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  280. @router.delete("/delete/{id}")
  281. async def delete_pattern(
  282. id: str,
  283. db: Session = Depends(get_db)
  284. ):
  285. try:
  286. # 检查图案是否存在
  287. info = classification_id_get_classification_info(db, id)
  288. if not info:
  289. return JSONResponse(status_code=404, content={"code": 404, "msg": "classification not found"})
  290. info.del_flag='2'
  291. db.commit()
  292. return {"code": 200, "msg": "删除成功"}
  293. except Exception as e:
  294. traceback.print_exc()
  295. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
  296. @router.put('/changeVisible')
  297. async def change_classification_visible(
  298. db: Session = Depends(get_db),
  299. body=Depends(remove_xss_json),
  300. user_id=Depends(valid_access_token)
  301. ):
  302. try:
  303. classification_id = body['classification_id']
  304. visible = body['visible']
  305. info = classification_id_get_classification_info(db, classification_id)
  306. if not info:
  307. return JSONResponse(status_code=404, content={"code": 404, "msg": "classification not found"})
  308. info.visible= visible
  309. info.update_by=user_id
  310. db.commit()
  311. return {
  312. "code": 200,
  313. "msg": "操作成功"
  314. }
  315. except Exception as e:
  316. # 处理异常
  317. traceback.print_exc()
  318. raise HTTPException(status_code=500, detail=str(e))
  319. @router.get("/templateTree")
  320. async def get_pattern_list(
  321. visible: str = Query(None, description='是否显示'),
  322. # page: int = Query(1, gt=0, description='页码'),
  323. # pageSize: int = Query(None, gt=0, description='每页条目数量'),
  324. db: Session = Depends(get_db)
  325. ):
  326. try:
  327. query = db.query(TpPatternTemplate)
  328. query = query.filter_by(del_flag='0')
  329. if visible is not None:
  330. query = query.filter_by(visible=visible)
  331. # if name:
  332. # query = query.filter(TpPatternTemplate.name.like(f'%{name}%'))
  333. # total_items = query.count()
  334. # # 排序
  335. # if pageSize is None:
  336. # pageSize=total_items
  337. query = query.order_by(TpPatternTemplate.order_num.asc())
  338. # 执行分页查询
  339. lists = query.all() # .offset((page - 1) * pageSize).limit(pageSize)
  340. data = []
  341. for info in lists:
  342. # print(1111)
  343. query1 = db.query(TpPatternClassification)
  344. query1 = query1.filter_by(template_id=info.template_id, del_flag='0')
  345. if visible is not None:
  346. query1 = query1.filter_by(visible=visible)
  347. query1 = query1.order_by(TpPatternClassification.order_num.asc())
  348. classification_list = query1.all()
  349. # =template_id_get_classification_list(db,info.template_id)
  350. template_info = {"template_id": info.template_id,
  351. "name": info.name,
  352. "value": info.value,
  353. "order_num": info.order_num,
  354. "visible": info.visible,
  355. "create_time": info.create_time}
  356. if classification_list:
  357. template_info['children']=[{"classification_id": classification.classification_id,
  358. "name": classification.name,
  359. "value": classification.value,
  360. "order_num": classification.order_num,
  361. "visible": classification.visible,
  362. "image": classification.image,
  363. "icon": classification.icon,
  364. "size": classification.size,
  365. "create_time": classification.create_time} for classification in classification_list]
  366. data.append(template_info)
  367. return {"code": 200, "msg": "查询成功", "data": data}
  368. except Exception as e:
  369. traceback.print_exc()
  370. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")