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 create(request: Request): data = await request.json() cmd = """\ INSERT INTO profile ( username, work_number, name, department, role, phone, email, password_hash ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)\ """ async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: try: await cur.execute( cmd, (data.get('username'), data.get('workNumber'), data.get('name'), data.get('department'), data.get('role'), data.get('phone'), data.get('email'), generate_password_hash('8888'))) await conn.commit() except IntegrityError: return code_response(RepetitionUserResponse) return code_response(ResponseOk)
async def verify_jwt_token(request: Request, handler): if any([ request.path.startswith(path) and request.method == method for path, method in WITHOUT_VERIFY ]): resp = await handler(request) return resp else: # 对jwt token检验 try: if match('/ws/.*', request.path): token = request.query['token'] else: token = request.headers.get('Authorization').split(' ')[-1] app = request.app except (AttributeError, KeyError, IndexError): return code_response(InvalidTokenResponse) try: content = jwt_decode(token, app['config']['jwt-secret'], algorithms=['HS256']) # 检查功能模块的权限 for pattern in MODULE_PERMISSION.keys(): if match(pattern, request.path): if content.get('rol') & MODULE_PERMISSION[pattern]: break else: return code_response(RepetitionLoginResponse) # 检测重复登录 try: _key = '{}:{}:jwt'.format(content.get('name'), content.get('dep')) _value = await request.app['redis'].get(_key) if _value: assert token == _value except AssertionError: return code_response(InvalidTokenResponse) request['jwt_content'] = content if await app['black_bf'].is_contain(token): # 是否在缓冲表中 if await app['redis'].exists('it:tmp-list:{}'.format(token)): resp = await handler(request) resp.headers['jwt_new_token'] = await app['redis'].get( 'it:tmp-list:{}'.format(token)) return resp else: return code_response(InvalidTokenResponse) else: resp = await handler(request) # 离过期不足5分钟,更新token if content.get('exp') <= (datetime.now() + timedelta(minutes=5)).timestamp(): # 在header加上新token,通过前端axios拦截下来,然后更新 resp.headers['jwt_new_token'] = await update_token( content, token, app) return resp except (InvalidSignatureError, ExpiredSignatureError, DecodeError): return code_response(InvalidTokenResponse)
async def patrol_check(request: Request): pid = get_query_params(request, 'pid') pd_id = get_query_params(request, 'pdId') eid = get_query_params(request, 'eid') async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( "UPDATE `patrol_detail` SET `check`=1 WHERE `id`=%s AND `pid`=%s AND `eid`=%s", (pd_id, pid, eid)) if cur.rowcount == 0: return code_response(EquipmentNotInPlanResponse) await cur.execute( "SELECT COUNT(*) FROM `patrol_detail` WHERE `pid`=%s AND `check`=0", pid) row = await cur.fetchone() if row: if row[0] == 0: # 如果全部check了则更新plan await cur.execute( "UPDATE `patrol_meta` SET `status`=1, `unfinished`=0 WHERE `id`=%s", pid) else: await cur.execute( "UPDATE `patrol_meta` SET `unfinished`=%s WHERE `id`=%s", (row[0], pid)) await conn.commit() return code_response(ResponseOk)
async def update(request: Request): # data {key: [new, old]} _eid = get_equipment_id(request) data = await request.json() try: assert all(field in EQUIPMENT_FIELDS for field in data) except AssertionError: return code_response(InvalidFormFIELDSResponse) _edit = request['jwt_content'].get('name') fields = tuple(data.keys()) cmd = "UPDATE equipment SET {}, `edit`=%s WHERE id=%s".format(','.join([f'`{field}`=%s' for field in fields])) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute(cmd, [data[field][0] for field in fields] + [_edit, _eid]) _content = '{} {} 修改了设备编号为 {} 的设备记录:{}'.format( datetime.now().strftime('%Y-%m-%d %H:%M:%S'), _edit, _eid, ', '.join(['{category}: {old} => {_new}'.format(category=field, old=data[field][1], _new=data[field][0]) for field in fields]) ) await cur.execute("INSERT INTO edit_history (eid, content, edit) VALUES (%s, %s, %s)", (_eid, _content, _edit)) await conn.commit() await set_cache_version(request, KEY_OF_VERSION) return code_response(ResponseOk)
async def change_status(request: Request): _eid = get_equipment_id(request) _edit = request['jwt_content'].get('name') try: data = await request.json() if data['status'] == 0: cmd = "UPDATE equipment SET status=0, user=%s, owner=%s, department=%s, edit=%s WHERE id=%s" params = (data['user'], data['owner'], data['department'], _edit, _eid) elif data['status'] in (2, 3): cmd = f"UPDATE equipment SET status={data['status']}, user='', owner='', department='', edit=%s WHERE id=%s" params = (_edit, _eid) else: return code_response(InvalidFormFIELDSResponse) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute(cmd, params) _content = '{} {} 将设备编号为 {} 的设备设置为 {} 状态'.format( datetime.now().strftime('%Y-%m-%d %H:%M:%S'), _edit, _eid, StatusText[data['status']] ) await cur.execute("INSERT INTO edit_history (eid, content, edit) VALUES (%s, %s, %s)", (_eid, _content, _edit)) await conn.commit() await set_cache_version(request, KEY_OF_VERSION) return code_response(ResponseOk) except KeyError: return code_response(InvalidFormFIELDSResponse)
async def create_hardware(request: Request): _eid = get_equipment_id(request) data = await request.json() async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: _cmd = """\ INSERT INTO computer_detail ( eid, ip_address, cpu, gpu, disk, `memory`, main_board, `monitor`, remark ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)\ """ try: await cur.execute(_cmd, ( _eid, data.get('ip'), data.get('cpu'), data.get('gpu'), data.get('disk'), data.get('memory'), data.get('main_board'), data.get('monitor'), data.get('remark') )) except IntegrityError: return code_response(RepetitionHardwareResponse) finally: await conn.commit() return code_response(ResponseOk)
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 alive(request: Request): # uid 是藏在jwt中的 if 'uid' in request['jwt_content']: return code_response( ResponseOk, { 'name': request['jwt_content']['name'], 'department': request['jwt_content']['dep'], 'role': request['jwt_content']['rol'], 'phone': request['jwt_content']['pho'], 'email': request['jwt_content']['email'], }) else: return code_response(NeedBindingResponse)
async def update_config(request: Request): # {key, value} try: data = await request.json() assert data['key'] in CONFIG_FIELDS assert 'value' in data except (AssertionError, AttributeError, JSONDecodeError): return code_response(InvalidFormFIELDSResponse) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: cmd = " UPDATE `it_config` SET `value`=%s WHERE `key`=%s " await cur.execute(cmd, (data['value'], data['key'])) await conn.commit() await set_config(request, data['key'], data['value']) return code_response(ResponseOk)
async def update_profile(request: Request): # {key, value} # 用户自己更新phone或者email _uid = get_jwt_user_id(request) try: data = await request.json() assert all(k in data for k in ['type', 'newValue']) 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 profile SET `{}`=%s WHERE id=%s'.format(data['type']), (data['newValue'], _uid)) await conn.commit() return code_response(ResponseOk)
async def get_email_content(request: Request): # case id 就是长的那个id case_id = get_case_id(request) _content = "" async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( "SELECT `content` FROM `email_history` WHERE `case_id`=%s", case_id) row = await cur.fetchone() await conn.commit() if row: _content = row[0] else: return code_response(MissEmailContentResponse) return code_response(ResponseOk, {'content': _content})
async def get_captcha(request: Request): _eid = get_equipment_id(request) try: _phone = request.query['phone'] except KeyError: raise HTTPForbidden(text='Miss phone') try: await send_sms(request, _eid, _phone) except RuntimeError: return code_response(SendSmsErrorResponse) except SmsLimitException: return code_response(SmsLimitResponse) return code_response(ResponseOk)
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 change_password(request: Request): data = await request.json() _uid = get_jwt_user_id(request) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute("SELECT * FROM profile WHERE id=%s", _uid) r = await cur.fetchone() await conn.commit() if r and check_password_hash(r[-3], data.get('originPassword')): await cur.execute( 'UPDATE profile SET password_hash=%s WHERE id=%s', (generate_password_hash(data.get('newPassword')), _uid)) await conn.commit() return code_response(ResponseOk) else: return code_response(InvalidOriginPasswordResponse)
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 stats_of_category(request: Request): cmd = "SELECT `category`, count(*) FROM equipment" filter_params = [] if request.query.get('category'): for _d in request.query.get('category').split(','): filter_params.append(f'`category`="{_d}"') if len(filter_params) > 1: filter_params = ' OR '.join(filter_params) elif len(filter_params) == 1: filter_params = filter_params[0] if filter_params: cmd += f' WHERE {filter_params}' cmd += ' GROUP BY `category`' async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: data = [] count = 0 await cur.execute(cmd) for row in await cur.fetchall(): data.append({'name': row[0], 'value': row[1]}) count += row[1] await conn.commit() return code_response(ResponseOk, {'total': count, 'sourceData': data})
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 preview_stats(request: Request): async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute(handle_filter_params(request) + " LIMIT 10") 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() return code_response(ResponseOk, data)
async def return_user_and_token_unregister(request: Request, user, resp): jwt_token = jwt_encode( { 'wxId': user['wx_id'], 'name': user['name'], 'number': user['number'], 'dep': '', 'rol': 0, 'pho': user['mobile'], '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('{}:unregister:jwt'.format(user['name']), jwt_token, expire=60 * 5) # 这是为了禁止重复登录 return code_response( resp, { 'token': jwt_token, 'user': { 'wxId': user['wx_id'], 'name': user['name'], 'number': user['number'], 'phone': user['mobile'], } })
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 update_permission(request: Request): _uid = get_user_id(request) data = await request.json() async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute('UPDATE profile SET role=%s WHERE id=%s', (data.get('permission'), _uid)) await conn.commit() return code_response(ResponseOk)
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 get_config(request: Request): # [[key, value], ...] async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: cmd = "SELECT * FROM `it_config`" await cur.execute(cmd) data = [] for row in await cur.fetchall(): data.append([row[1], row[2]]) await conn.commit() return code_response(ResponseOk, data)
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 delete_patrol(request: Request): pid = get_patrol_id_in_uri(request) async with request.app['mysql'].acquire() as conn: async with conn.cursor() as cur: await cur.execute( "UPDATE `patrol_meta` SET del_flag=1 WHERE id=%s", pid) await cur.execute( "UPDATE `patrol_detail` SET del_flag=1 WHERE pid=%s", pid) await conn.commit() return code_response(ResponseOk)
async def cancel(request: Request): # data { name, phone, remark } """ *(E/F) -> C 取消工单 """ _oid = get_maintenance_id(request) _eid = get_equipment_id(request) data = await request.json() _time_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S') try: _edit = data['name'] _phone = data['phone'] _content = "{time} {name}({phone}) 已取消工单".format( time=_time_str, name=_edit, phone=_phone, ) 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`='C', `content`=%s WHERE `id`=%s AND `status` NOT IN ('E', 'F')" await cur.execute(m_cmd, (_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, 'C', _edit, _phone, data.get('remark'), _content) # await cur.execute(H_CMD, (_oid, 'C', _edit, _phone, data.get('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 login(request: Request): data = await request.json() if match(r'^\d+', data.get('username')): _username = ('work_number', data.get('username')) else: _username = ('username', data.get('username')) user = await verify_login(request.app['mysql'], _username, data.get('password')) if user: return await return_user_and_token(request, user) else: return code_response(InvalidUserDataResponse)
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)