async def equipment_output(request: Request): # { eids: [] } try: _data = await request.json() _eids = [ItHashids.decode(_eid) for _eid in _data['eids']] except (KeyError, JSONDecodeError): return code_response(InvalidFormFIELDSResponse) fn = '{}.xlsx'.format(datetime.now().strftime("%Y%m%d%H%M")) workbook = Workbook(os.path.join(DOWNLOAD_DIR, fn)) sheet = workbook.add_worksheet() row = 0 for col, v in enumerate(['设备分类', '所属部门', '责任人', '二维码网址']): sheet.write(row, col, v) row += 1 cmd = """ SELECT `category`, `department`, `owner`, `id` FROM `equipment` WHERE `id` IN ({}) """.format(','.join(['%s' for _ in _eids])) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute(cmd, _eids) for r in await cur.fetchall(): for col, v in enumerate(r): if col + 1 == len(r): # 对id做处理 sheet.write(row, col, get_detail_uri(ItHashids.encode(v))) else: sheet.write(row, col, v) row += 1 await conn.commit() workbook.close() return code_response(ResponseOk, {'uri': f'/api/download/{fn}', 'name': fn})
async def get_personal_maintenance(request: Request): uid = ItHashids.decode(request['jwt_content']['uid']) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( """\ SELECT a.`id`, a.`order_id`, a.`status`, a.`eid`, a.`equipment`, a.`department`, a.`reason`, b.`name`, b.`phone` FROM `order` a JOIN `order_history` b ON a.`id` = b.`oid` WHERE a.`pid`=%s AND (a.`status` IN ('D', 'H')) AND a.`del_flag`=0 AND b.`status`='R' ORDER BY `id` DESC LIMIT 20\ """, uid) res = [] for row in await cur.fetchall(): res.append({ 'oid': ItHashids.encode(row[0]), 'orderId': row[1], 'status': row[2], 'eid': ItHashids.encode(row[3]), 'equipment': row[4], 'department': row[5], 'reason': row[6], 'name': row[7], 'phone': row[8], }) await conn.commit() return code_response(ResponseOk, res)
async def return_user_and_token(request: Request, user): jwt_token = jwt_encode( { 'uid': ItHashids.encode(user.id), 'name': user.name, 'dep': user.department, 'rol': user.role, 'pho': user.phone, 'email': user.email, 'iat': round(datetime.now().timestamp()), 'exp': round((datetime.now() + timedelta(hours=24)).timestamp()) }, request.app['config']['jwt-secret'], algorithm='HS256').decode('utf-8') await request.app['redis'].set('{}:{}:jwt'.format(user.name, user.department), jwt_token, expire=60 * 60 * 24) # 这是为了禁止重复登录 return code_response( ResponseOk, { 'token': jwt_token, 'user': { 'name': user.name, 'department': user.department, 'role': user.role, 'phone': user.phone, 'email': user.email, } })
async def get_department_contact(request: Request): """ 获取单个部门的联系人信息 """ try: did = ItHashids.decode(request.query['did']) except KeyError: return code_response(InvalidFormFIELDSResponse) cmd = f"""\ SELECT a.did, a.pid, b.name, b.phone FROM `department_contact` a JOIN `profile` b ON a.pid = b.id WHERE a.did = %s """ res = { 'name': '', 'phone': '', } async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute(cmd, did) row = await cur.fetchone() if row: res['name'] = row[2] res['phone'] = row[3] await conn.commit() return code_response(ResponseOk, res)
async def equipment_detail(request: Request): _eid = get_equipment_id(request) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute("SELECT * FROM equipment WHERE `id`=%s", (_eid,)) row = await cur.fetchone() res = { 'eid': ItHashids.encode(row[0]), 'category': row[1], 'brand': row[2], 'modelNumber': row[3], 'serialNumber': row[4], 'price': row[5], 'purchasingTime': row[6].strftime('%Y-%m-%d'), 'guarantee': row[7], 'remark': row[8], 'status': row[9], 'user': row[10], 'owner': row[11], 'department': row[12], 'edit': row[13], 'del_flag': row[14], } await conn.commit() return code_response(ResponseOk, res)
async def create_patrol(request: Request): # { pid: str, eids: [] } try: _data = await request.json() _eids = [ItHashids.decode(_eid) for _eid in _data['eids']] _pid = ItHashids.decode(_data['pid']) _email = _data['email'] _start_time = _data['startTime'] _end_time = _data['endTime'] except (KeyError, AssertionError, JSONDecodeError): return code_response(InvalidFormFIELDSResponse) _patrol_id = await get_patrol_id(request) m_cmd = """\ INSERT INTO `patrol_meta` ( patrol_id, pid, total, unfinished, start_time, end_time ) VALUES (%s, %s, %s, %s, %s, %s)\ """ d_cmd = """ INSERT INTO `patrol_detail` ( pid, eid ) VALUES (%s, %s)\ """ async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: try: await cur.execute(m_cmd, (_patrol_id, _pid, len(_eids), len(_eids), _start_time, _end_time)) except IntegrityError: return code_response(RepetitionOrderIdResponse) _last_row_id = cur.lastrowid await cur.executemany(d_cmd, [(_last_row_id, _eid) for _eid in _eids]) await conn.commit() await send_patrol_email(request, _last_row_id, _patrol_id, create_captcha(), _email) return code_response(ResponseOk)
async def query_without_pagination(request: Request): # 不做304 # 判断root,且不做304 cmd = "SELECT * FROM equipment" filter_params = [] # 对过滤项进行组合处理 for type_, col_format in zip( ['department', 'equipment', 'status'], ['department="{}"', 'category="{}"', 'status={}'] ): if request.query.get(type_): _tmp = [] for d in request.query.get(type_).split(','): _tmp.append(col_format.format(d)) if len(_tmp) > 1: filter_params.append("({})".format(' OR '.join(_tmp))) elif len(_tmp) == 1: filter_params.append(_tmp[0]) filter_part = ' AND '.join(filter_params) if request['jwt_content'].get('rol') & Permission.SUPER and request.query.get('all'): pass else: filter_part = 'del_flag=0' + (' AND ' if filter_part else '') + filter_part if filter_part: filter_part = ' WHERE ' + filter_part async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute(cmd + filter_part) data = [] for row in await cur.fetchall(): data.append({ 'eid': ItHashids.encode(row[0]), 'category': row[1], 'brand': row[2], 'modelNumber': row[3], 'serialNumber': row[4], 'price': row[5], 'purchasingTime': row[6].strftime('%Y-%m-%d'), 'guarantee': row[7], 'remark': row[8], 'status': row[9], 'user': row[10], 'owner': row[11], 'department': row[12], 'edit': row[13], 'del_flag': row[14], }) await conn.commit() resp = code_response(ResponseOk, data) return resp
async def remote_handle(request: Request): # data {eid, method, remark} """ R -> E 远程解决问题 """ _oid = get_maintenance_id(request) data = await request.json() try: assert all(k in data for k in REMOTE_HANDLE_FIELDS) except AssertionError: return code_response(InvalidFormFIELDSResponse) _time_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S') _eid = ItHashids.decode(data['eid']) _phone = request['jwt_content'].get('pho') _edit = request['jwt_content'].get('name') _pid = ItHashids.decode(request['jwt_content'].get('uid')) _content = "{time} {name}({phone}) 远程解决了故障".format(time=_time_str, name=_edit, phone=_phone) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: # todo 将更新状态抽象出来 # 更新order m_cmd = f"UPDATE {TABLE_NAME} SET status='E', pid=%s, name=%s, content=%s WHERE id=%s AND status='R'" await cur.execute(m_cmd, (_pid, _edit, _content, _oid)) if cur.rowcount == 0: return code_response(ConflictStatusResponse) # 更新equipment await cur.execute( "UPDATE equipment SET status=0, edit=%s WHERE id=%s AND status=1", (_edit, _eid)) if cur.rowcount == 0: return code_response(ConflictStatusResponse) await handle_order_history(cur, _oid, 'E', _edit, _phone, f"{data['method']}|{data['remark']}", _content) # await cur.execute(H_CMD, (_oid, 'E', _edit, _phone, f"{data['method']}|{data['remark']}", _content)) await handle_equipment_history( cur, _eid, _edit, '{} {} 修复设备故障'.format(_time_str, _edit)) # await cur.execute("INSERT INTO edit_history (eid, content, edit) VALUES (%s, %s, %s)", # (_eid, # '{} {} 修复设备故障'.format(_time_str, _edit), # _edit)) await conn.commit() return code_response(ResponseOk)
async def set_department_contact(request: Request): """ 设置单个部门的联系人信息 """ try: data = await request.json() did = ItHashids.decode(data['did']) pid = ItHashids.decode(data['pid']) assert all(k in data for k in ['did', 'pid']) except (AssertionError, AttributeError, JSONDecodeError): return code_response(InvalidFormFIELDSResponse) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( "UPDATE `department_contact` SET `pid`=%s WHERE `did`=%s", (pid, did)) if cur.rowcount == 0: await cur.execute( "INSERT INTO `department_contact` (`did`, `pid`) VALUES (%s, %s)", (did, pid)) await conn.commit() return code_response(ResponseOk)
async def get_personal_patrol_plan(request: Request): uid = ItHashids.decode(request['jwt_content']['uid']) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( """\ SELECT * FROM `patrol_meta` WHERE `pid`=%s AND `status`=0 AND `del_flag`=0 ORDER BY `id` DESC LIMIT 20\ """, uid) res = [] for row in await cur.fetchall(): res.append({ 'pid': ItHashids.encode(row[0]), 'patrolId': row[1], 'total': row[3], 'unfinished': row[4], 'status': row[5], 'gmt': row[7].strftime('%Y-%m-%d') }) await conn.commit() return code_response(ResponseOk, res)
async def get_patrol_detail(request: Request): """ 查看巡检计划的所有设备 """ pid = get_patrol_detail_id(request) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( """\ SELECT b.`department`, b.`category`, a.`check`, a.`gmt_modified`, a.`id`, a.`pid` FROM `patrol_detail` a JOIN `equipment` b ON a.`eid` = b.`id` WHERE `pid`=%s\ """, pid) data = [] for row in await cur.fetchall(): data.append({ 'department': row[0], 'category': row[1], 'check': row[2], 'checkTime': row[3].strftime('%Y-%m-%d'), 'pdId': ItHashids.encode(row[4]), 'pid': ItHashids.encode(int(row[5])), }) await conn.commit() return code_response(ResponseOk, data)
async def get_maintenance_workers(request: Request): res = [] async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( f"SELECT `id`, `name`, `phone`, `email`, `role` FROM profile WHERE role & {Permission.MAINTENANCE}" ) for row in await cur.fetchall(): if row[-1] & Permission.SUPER: continue res.append({ "pid": ItHashids.encode(row[0]), "name": row[1], "phone": row[2], "email": row[3], }) return code_response(ResponseOk, res)
async def get_patrol_plan(request: Request): try: page = int(request.query.get('page')) or 1 except ValueError: return code_response(MissRequiredFieldsResponse) cmd = f"""\ SELECT a.id, a.patrol_id, b.name, a.total, a.status, a.unfinished, a.start_time, a.end_time FROM {PATROL_TABLE} a JOIN `profile` b ON a.pid = b.id WHERE a.del_flag = 0 """ cmd += ' ORDER BY id DESC' + ' LIMIT {}, {}'.format( (page - 1) * PAGE_SIZE, PAGE_SIZE) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: # 计算总页数 await cur.execute( f"SELECT COUNT(*) FROM {PATROL_TABLE} WHERE del_flag = 0") sum_of_equipment = (await cur.fetchone())[0] total_page = sum_of_equipment // PAGE_SIZE if sum_of_equipment % PAGE_SIZE: total_page += 1 await cur.execute(cmd) data = [] for row in await cur.fetchall(): data.append({ 'pid': ItHashids.encode(row[0]), 'patrolId': row[1], 'name': row[2], 'total': row[3], 'status': row[4], 'unfinished': row[5], 'startTime': row[6], 'endTime': row[7], }) await conn.commit() resp = code_response(ResponseOk, { 'totalPage': total_page, 'tableData': data }) # resp.set_cookie(f'{KEY_OF_VERSION}-version', await get_cache_version(request, KEY_OF_VERSION)) return resp
async def dispatch_query(request: Request): """ 获取维修人员名单 """ async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: cmd = "SELECT * FROM profile WHERE role & {}".format( Permission.MAINTENANCE) await cur.execute(cmd) data = [] for row in await cur.fetchall(): if row[6] & Permission.SUPREME: pass data.append({ 'pid': ItHashids.encode(row[0]), 'name': row[3], 'phone': row[5] }) await conn.commit() return code_response(ResponseOk, data)
async def query(request: Request): async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute("SELECT * FROM profile") # todo 根据权限来看,不能直接是所有 data = [] for row in await cur.fetchall(): if row[6] & Permission.SUPREME: continue data.append({ 'uid': ItHashids.encode(row[0]), 'username': row[1], 'workNumber': row[2], 'name': row[3], 'department': row[4], 'phone': row[5], 'role': row[6], 'email': row[-2], }) await conn.commit() return code_response(ResponseOk, data)
async def get_maintenance_by_equipment(request: Request): eid = get_equipment_id(request) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( """\ SELECT `id`, `order_id`, `status` FROM `order` WHERE `eid`=%s AND `status`!='F' ORDER BY `id` DESC LIMIT 1""", eid) row = await cur.fetchone() if row: data = { 'oid': ItHashids.encode(row[0]), 'orderId': row[1], 'status': row[2] } await conn.commit() return code_response(ResponseOk, data) else: return code_response(EquipmentWithoutMaintenanceResponse)
async def get_patrol_detail(request: Request): """ 查看单个设备的巡检记录 """ eid = get_equipment_id(request) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( """ SELECT b.id, b.patrol_id FROM patrol_detail a JOIN patrol_meta b ON a.pid = b.id WHERE a.eid = %s AND a.`check` = 0; """, eid) data = [] for row in await cur.fetchall(): data.append({ 'pid': ItHashids.encode(row[0]), 'patrolId': row[1], }) await conn.commit() return code_response( ResponseOk, data) if len(data) else code_response(EmtpyPatrolPlanResponse)
async def dispatch(request: Request ): # data { worker: {pid, name, phone, email}, remark } """ R -> D 派单 """ _oid = get_maintenance_id(request) data = await request.json() _time_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S') try: _worker = data['worker'] _pid = ItHashids.decode(_worker['pid']) _edit = request['jwt_content'].get('name') _order_id = data['orderId'] _content = "{time} {name} 将工单分派给了 {worker}".format( time=_time_str, name=_edit, worker=_worker['name']) except KeyError: return code_response(InvalidFormFIELDSResponse) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: # 更新order m_cmd = f"UPDATE {TABLE_NAME} SET status='D', pid=%s, name=%s, content=%s WHERE id=%s AND status='R'" await cur.execute(m_cmd, (_pid, _worker['name'], _content, _oid)) if cur.rowcount == 0: return code_response(ConflictStatusResponse) await handle_order_history(cur, _oid, 'D', _worker['name'], None, data.get('remark'), _content) # await cur.execute(H_CMD, (_oid, 'D', _worker['name'], None, data.get('remark'), _content)) # 应该在history中记录被指派人的信息 await conn.commit() try: await send_maintenance_order_email(request, _oid, _order_id, create_captcha(), _worker['email']) except RuntimeError: return code_response(OrderMissContentResponse) except TimeoutError: return code_response(DispatchSuccessWithoutSendEmailResponse) return code_response(ResponseOk)
async def query(request: Request): # 不做304 # 判断root,且不做304 try: page = int(request.query.get('page')) if request.query.get('page') else 1 except ValueError: return code_response(MissRequiredFieldsResponse) cmd = "SELECT * FROM equipment" filter_params = [] # 暂时不做单个部门的过滤 # if request['jwt_content'].get('rol') & Permission.HIGHER: # cmd = "SELECT * FROM equipment WHERE del_flag=0" # else: # cmd = "SELECT * FROM equipment WHERE del_flag=0 AND department='{}'".format( # request['jwt_content'].get('dep')) # 对过滤项进行组合处理 for type_, col_format in zip( ['department', 'equipment', 'status'], ['department="{}"', 'category="{}"', 'status={}'] ): if request.query.get(type_): _tmp = [] for d in request.query.get(type_).split(','): _tmp.append(col_format.format(d)) if len(_tmp) > 1: filter_params.append("({})".format(' OR '.join(_tmp))) elif len(_tmp) == 1: filter_params.append(_tmp[0]) # if request.query.get('equipment'): # _tmp = [] # for d in request.query.get('equipment').split(','): # filter_params.append(f'category="{d}"') # filter_params.append(' OR '.join(_tmp)) # if request.query.get('status'): # _tmp = [] # for d in request.query.get('status').split(','): # filter_params.append(f'status={d}') # filter_params.append(' OR '.join(_tmp)) filter_part = ' AND '.join(filter_params) if request['jwt_content'].get('rol') & Permission.SUPER and request.query.get('all'): pass else: filter_part = 'del_flag=0' + (' AND ' if filter_part else '') + filter_part if filter_part: filter_part = ' WHERE ' + filter_part # 翻页逻辑 cmd = cmd + filter_part + ' limit {}, {}'.format((page - 1) * PAGE_SIZE, PAGE_SIZE) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: # 计算总页数 await cur.execute("SELECT COUNT(*) FROM equipment" + filter_part) sum_of_equipment = (await cur.fetchone())[0] total_page = sum_of_equipment // PAGE_SIZE if sum_of_equipment % PAGE_SIZE: total_page += 1 await cur.execute(cmd) data = [] for row in await cur.fetchall(): data.append({ 'eid': ItHashids.encode(row[0]), 'category': row[1], 'brand': row[2], 'modelNumber': row[3], 'serialNumber': row[4], 'price': row[5], 'purchasingTime': row[6].strftime('%Y-%m-%d'), 'guarantee': row[7], 'remark': row[8], 'status': row[9], 'user': row[10], 'owner': row[11], 'department': row[12], 'edit': row[13], 'del_flag': row[14], }) await conn.commit() resp = code_response(ResponseOk, { 'totalPage': total_page or 1, # 为0的时候前端会有问题 'tableData': data }) resp.set_cookie(f'{KEY_OF_VERSION}-version', await get_cache_version(request, KEY_OF_VERSION)) return resp
async def query(request: Request): try: page = int(request.query.get('page')) or 1 except ValueError: return code_response(MissRequiredFieldsResponse) cmd = f"SELECT * FROM {TABLE_NAME}" filter_params = [] # 暂时不做单个部门的过滤 # 对过滤项进行组合处理 for type_, col_format in zip( ['department', 'equipment', 'status'], ['department="{}"', 'equipment="{}"', 'status="{}"' ] # 注意这里,equipment的status是int,maintenance是string ): if request.query.get(type_): _tmp = [] for d in request.query.get(type_).split(','): _tmp.append(col_format.format(d)) if len(_tmp) > 1: filter_params.append("({})".format(' OR '.join(_tmp))) elif len(_tmp) == 1: filter_params.append(_tmp[0]) filter_part = ' AND '.join(filter_params) if request['jwt_content'].get( 'rol') & Permission.SUPER and request.query.get('all'): pass else: filter_part = 'del_flag=0' + (' AND ' if filter_part else '') + filter_part if filter_part: filter_part = ' WHERE ' + filter_part # 翻页逻辑 cmd += filter_part cmd += ' ORDER BY id DESC' + ' limit {}, {}'.format( (page - 1) * PAGE_SIZE, PAGE_SIZE) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: # 计算总页数 await cur.execute(f"SELECT COUNT(*) FROM {TABLE_NAME}" + filter_part) sum_of_equipment = (await cur.fetchone())[0] total_page = sum_of_equipment // PAGE_SIZE if sum_of_equipment % PAGE_SIZE: total_page += 1 await cur.execute(cmd) data = [] for row in await cur.fetchall(): data.append({ 'oid': ItHashids.encode(row[0]), 'orderId': row[1], 'status': row[2], 'pid': ItHashids.encode(row[3]) if row[3] else row[3], 'name': row[4], 'eid': ItHashids.encode(row[5]), 'equipment': row[6], 'department': row[7], # 'content': row[8], 'reason': row[9], 'rank': row[10], 'del_flag': row[11], }) await conn.commit() resp = code_response( ResponseOk, { 'totalPage': total_page or 1, # 为0的时候前端会有问题 'tableData': data }) resp.set_cookie(f'{KEY_OF_VERSION}-version', await get_cache_version(request, KEY_OF_VERSION)) return resp
async def report_order(request: Request): # {eid, reportForm} try: _data = await request.json() _eid = ItHashids.decode(_data['eid']) _report_form = _data['reportForm'] assert all(k in REPORT_FORM_FIELDS for k in _report_form) except (KeyError, AssertionError, JSONDecodeError): return code_response(InvalidFormFIELDSResponse) _time_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 不上传验证码时就不检验了 if _report_form.get('captcha') == '' or await check_sms_captcha( request, _eid, _report_form['phone'], _report_form['captcha']): async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: # 确认设备状态为正常 await cur.execute( "SELECT `department`, `category` FROM equipment WHERE `id`=%s AND `status`=0", (_eid, )) if cur.rowcount == 0: return code_response(ConflictStatusResponse) else: row = await cur.fetchone() _department = row[0] _equipment = row[1] _content = "{time} {department} {name}({phone}) 上报了 {equipment} 故障,原因是{reason}".format( time=_time_str, department=_department, name=_report_form['name'], phone=_report_form['phone'], equipment=_equipment, reason=_report_form['reason']) _edit = _report_form['name'] try: _order_id = await get_order_id(request) m_cmd = """\ INSERT INTO `order` ( order_id, eid, equipment, department, content, reason ) VALUES (%s, %s, %s, %s, %s, %s)\ """ await cur.execute( m_cmd, (_order_id, _eid, _equipment, _department, _content, _report_form['reason'])) except IntegrityError: return code_response(RepetitionOrderIdResponse) _last_row_id = cur.lastrowid await handle_order_history(cur, _last_row_id, 'R', _report_form['name'], _report_form['phone'], _report_form.get('remark'), _content) # await cur.execute(H_CMD, ( # _last_row_id, 'R', _report_form['name'], _report_form['phone'], _report_form.get('remark'), # _content)) # 更新equipment # await cur.execute("UPDATE equipment SET oid=%s, status=1, edit=%s WHERE id=%s", # (_last_row_id, _edit, _eid)) await cur.execute( "UPDATE equipment SET status=1, edit=%s WHERE id=%s", (_edit, _eid)) await handle_equipment_history( cur, _eid, _edit, '{} {} 上报了编号为 {} 的设备故障'.format(_time_str, _edit, _eid)) # await cur.execute("INSERT INTO edit_history (eid, content, edit) VALUES (%s, %s, %s)", # (_eid, # '{} {} 上报了编号为 {} 的设备故障'.format(_time_str, _edit, _eid), # _edit)) await conn.commit() # 更新redis中的order id和order版本 # await set_cache_version(request, 'order') # await set_cache_version(request, 'equipment') return code_response(ResponseOk) else: return code_response(InvalidCaptchaResponse)
async def add(request: Request): tree = Tree(pool=request.app['mysql']) data = await request.json() await tree.add_node(data['label'], ItHashids.decode(data['parentId'])) await set_cache_version(request, KEY_OF_VERSION) return code_response(ResponseOk)
def get_jwt_user_id(request: Request): return ItHashids.decode(request['jwt_content']['uid'])