def content_detail(req, id): """ 查询blog明细 :param req: request :param id: id :return: """ ret = ResModel() ret.msg = req_invalid_check(req) v_cnt = 0 if not req.GET.get("forManage"): # 不 通过管理端查询 # 浏览者信息登记 try: ip = get_ip(req) v_cnt = add_visitor(ip, apps.get_app_config('app_blog').name, 'read', id) except: from traceback import format_exc flog.error("记录访客信息失败:%s" % format_exc()) if ret.msg: # 请求合法性校验不通过 ret.code = ret.ResCode.fail ret.data = {} return JsonResponse(ret.to_dic()) ret.code = ret.ResCode.succ # todo 权限level的控制 # 为了统一,驼峰命名,采用原生sql with connection() as con: # where 条件 and {table1_rlevel}>=0 暂时先屏蔽 rs = con.execute_sql( """select {table1_id},{table1_title},{table1_content},{table1_rcnt}, to_char({table1_atime}, 'yyyy-mm-dd hh24:mi:ss') as {table1_atime}, {table1_notes},{table1_bgurl},{table1_rlevel},{table1_type_id},{table1_tags} from {table1} where {table1_id}=%(id)s """.format(**SQL_DIC_BLOG), {"id": id}, dicorobj="dict") if rs: ret.data = rs[0] if v_cnt == 1: con.execute_sql( "update {table1} set {table1_rcnt}={table1_rcnt}+1 where {table1_id}=%(id)s" .format(**SQL_DIC_BLOG), {"id": id}) else: ret.data = {} return JsonResponse(ret.to_dic())
def get_menulist_role(req, role_id=None): """ 根据角色获取菜单 :param req: :param role_id: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) if not role_id: roleMenus = DrRoleMenu.objects.filter() else: roleMenus = DrRoleMenu.objects.filter(role_id=role_id) # ids存储当前角色已有的菜单id ids = [] for row in roleMenus: ids.append(row.menu_id) tops = DrMenu.objects.filter(Q(pid='') | Q(pid__isnull=True)).order_by('order_no') ret.data = menu_children(tops, ids) ret.msg = '' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def get_info(req): """ 查询信息 :param req: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) # 中间件校验token后赋值USER_ID user_id = req.META.get("USER_ID") if user_id: # 查询用户信息 with connection() as con: user_rs = con.execute_sql(""" select a.{table1_uname},a.{table1_phone},a.{table1_email},a.{table1_emailsucc}, a.{table1_wx},a.{table1_qq},to_char(a.{table1_atime}, 'yyyy-mm-dd hh24:mi:ss') as {table1_atime}, b.{table11_sex},b.{table11_himg},b.{table11_introduce},b.{table11_notes},b.{table11_occupation}, b.{table11_local} from {table1} a,{table11} b where a.{table1_id}=b.{table11_id} and a.{table1_id}=%(uid)s""" .format(**{ **SQL_DIC_USER, **SQL_DIC_USERINFO }), {"uid": user_id}, dicorobj='dict') if user_rs and user_rs[0]: ret.data = user_rs[0] ret.code = ret.ResCode.succ ret.msg = "" return JsonResponse(ret.to_dic())
def title_value(req): """ 查询副标题参数 :param req: request :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 ret.code = ret.ResCode.fail ret.data = {} return JsonResponse(ret.to_dic()) ret.code = ret.ResCode.succ with connection() as con: rs = con.execute_sql( "select {table1_value} from {table1} where {table1_code}=%(p)s ". format(**SQL_DIC_PARAM), {'p': SET_TITLE_CMD}, dicorobj="dict") ret.data = rs[0] if rs else {} return JsonResponse(ret.to_dic())
def type_list(req): """ 查询blog类别 :param req: request :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 ret.code = ret.ResCode.fail ret.data = [] return JsonResponse(ret.to_dic()) ret.code = ret.ResCode.succ with connection() as con: ret.data = con.execute_sql( """select {table2_type_id}, {table2_type_name} from {table2} order by convert_to({table2_type_name} , 'GB18030') asc""" .format(**SQL_DIC_TYPE), dicorobj="dict") return JsonResponse(ret.to_dic())
def wsocket_init(req): """ websocket连接初始化 https://blog.csdn.net/xianailili/article/details/82180114 :param req: :return: """ ret = ResModel() ret.code = ret.ResCode.succ ret.msg = "" if req.is_websocket(): # rlock线程锁 lock = RLock() try: # 抢占资源 lock.acquire() global WS_OBJ w_obj = req.websocket WS_OBJ.add(w_obj) ret.data = {"nowCnt": len(WS_OBJ), "type": "init"} ret_final = dumps(ret.to_dic(), ensure_ascii=False).encode('utf-8') w_obj.send(ret_final) for m in w_obj: if not m: break print('客户端消息:', m.decode('utf-8')) ret.data = {"nowCnt": len(WS_OBJ), "clientMsg": m.decode('utf-8'), "type": "return"} ret_final = dumps(ret.to_dic(), ensure_ascii=False).encode('utf-8') w_obj.send(ret_final) except: pass finally: # 移除当前在线的websocket对象 WS_OBJ.remove(w_obj) # 释放锁 lock.release()
def api_websocket_msg(req): """ 发送消息-api :param req: :return: """ ret = ResModel() ret.code = ret.ResCode.succ ret.msg = "" data = loads(req.POST.get("data", "{}")) ret.data = {"nowCnt": len(WS_OBJ), "type": "yw", "data": data} ret_final = ret.to_dic() websocket_send_all(ret_final) return JsonResponse(ret_final)
def vcode_sid(req): """ 验证码-获取sid 生成sid及验证码字符串,有效期10分钟 :param req: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) r = RedisCtrl() ret.data = str(uuid1()).replace("-", "").lower() r.set_one(REDIS_KEY_PRE_SID + ret.data, ValidCodeImg.getRandomStr(5), expt=60 * 10) ret.msg = '' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def upload_file(req): """ 文件上传 :param req: pathPre,file :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) file_obj = req.FILES.get('file') if not file_obj: ret.msg = '未选择文件' return JsonResponse(ret.to_dic()) # 允许指定类型前缀,以区分不同业务 path_pre = req.POST.get('pathPre', '') # 上传路径 up_path_pre = settings.UPLOAD_DIR # 按日期年月分组 now_date = fmt_date(fmt=FMT_DATE) up_path = path.join(up_path_pre, path_pre, now_date) if not path.exists(up_path): makedirs(up_path) # 重命名,防止重名 file_type = path.splitext(file_obj.name)[1] file_name = str(uuid1()).replace('-', '') + file_type # 保存文件 with open(path.join(up_path, file_name), 'wb') as fp: for chunk in file_obj.chunks(): fp.write(chunk) ret.msg = '已上传' ret.code = ret.ResCode.succ # fileSize单位是字节.fileSize/1024单位即kb;fileSize/1024/1024单位即mb ret.data = {"oldName": file_obj.name, "newName": path.join(settings.STATIC_ROOT, settings.UPLOAD_ROOT, path_pre, now_date, file_name), "fileType": file_type.split(".")[-1], "fileSize": file_obj.size} return JsonResponse(ret.to_dic())
def get_display_list(req): """ 角色列表-带pid的树形 :param req: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 ret.code = ret.ResCode.fail return JsonResponse(ret.to_dic()) with connection() as con: ret.data = con.execute_sql( """select a.{tablem_id} as id,a.{tablem_aname} as name,a.{tablem_pid} as p_id from {tablem} a where 1=1 order by a.{tablem_orderno} asc,a.{tablem_id} asc""" .format(**SQL_DIC_MENU), dicorobj="dict") ret.code = ret.ResCode.succ ret.msg = "" return JsonResponse(ret.to_dic())
def sid_pic(req, sid): """ 验证码-根据sid生成图片 :param req: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: # 正常情况下get_sid和本函数是无间隔顺序调用的,所以不会出现redis中不存在的情况,不必友好提示 return JsonResponse(ret.to_dic()) # 生成验证码图片. i = ValidCodeImg(code_count=5, img_format='png') img_data, valid_str = i.getValidCodeImg(vcode_str=verify_code) ret.data = img_data.decode('utf8') ret.msg = '' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def get_allmenu2list(req): """ get_allmenu2list :param req: :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 return JsonResponse(ret.to_dic()) # 中间件校验token后赋值USER_ID user_id = req.META.get("USER_ID") sql = """select * from (select prt.{tablem_id} {tablem_id}, prt.{tablem_sname}, prt.{tablem_aname}, prt.{tablem_href}, prt.{tablem_icon}, prt.{tablem_orderno} {tablem_orderno}, chd.{tablem_id} child_id, chd.{tablem_sname} child_show_name, chd.{tablem_aname} child_alias_name, chd.{tablem_href} child_href, chd.{tablem_icon} child_icon, chd.{tablem_orderno} child_order_no, chd.{tablem_pid} child_parent_id from {tablem} prt left join {tablem} chd on chd.{tablem_pid} = prt.{tablem_id} where prt.{tablem_pid} is null or prt.{tablem_pid} = '') menu where menu.child_id in ( select rm.{tablerm_mid} from {table1} u, {table3} ur, {tablerm} rm where u.{table1_id} = ur.{table3_uid} and ur.{table3_rid} = rm.{tablerm_rid} and u.{table1_id} = %(uid)s) or (menu.{tablem_id} in ( select rm.{tablerm_mid} from {table1} u, {table3} ur, {tablerm} rm where u.{table1_id} = ur.{table3_uid} and ur.{table3_rid} = rm.{tablerm_rid} and u.{table1_id} = %(uid)s) and (menu.child_id is null or menu.child_id = '')) order by menu.{tablem_orderno}, menu.child_order_no """ ret.data = [] menuIdLst = [] with connection() as con: menu_list = con.execute_sql( sql.format( **{ **SQL_DIC_MENU, **SQL_DIC_ROLEMENU, **SQL_DIC_USER, **SQL_DIC_USERROLE }), {"uid": user_id}) for row in menu_list: if row.id in menuIdLst: continue menuIdLst.append(row.id) menuObj = { "menuId": row.id, "showName": row.showName, "aliasName": row.aliasName, "href": row.href, "icon": row.icon, "orderNo": row.orderNo } if row.childId: menuObj["hasChildren"] = True parentId = row.id children = [] for child in menu_list: if parentId == child.childParentId: childObj = { "menuId": child.childId, "showName": child.childShowName, "aliasName": child.childAliasName, "href": child.childHref, "icon": child.childIcon, "orderNo": child.childOrderNo } children.append(childObj) menuObj["children"] = children else: menuObj["hasChildren"] = False ret.data.append(menuObj) ret.msg = '' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())
def log_in_openid(req, yw_name, openid): """ 根据openid登录 1.查询redis是否存在该openid用户: 1.1.存在则直接return 1.2.不存在则查询db: a.获取用户信息存入redis后return b.无用户信息则return空,可走注册流程 :param req: :param yw_name: :param openid: :return: """ ret = ResModel() app_idsecret = MINI_PROGRAM_APP_CONF.get(yw_name) if not app_idsecret: ret.msg = '未配置的应用名称' return JsonResponse(ret.to_dic()) ret.msg = '' ret.code = ret.ResCode.succ app_id, app_secret = app_idsecret user_obj = None r = RedisCtrl() token = r.get_one(app_id + openid) if token: user_obj = r.get_one(token) else: with connection() as con: sql = """select a.{table1_id}, a.{table1_uname}, a.{table1_pwd}, a.{table1_salt}, a.{table1_wx}, a.{table1_qq}, a.{table1_phone}, a.{table1_email} from {table1} a, {tableo} b where a.{table1_id}=b.{tableo_uid} and b.{tableo_aid}=%(appid)s and b.{tableo_oid}=%(oid)s """.format(**{**SQL_DIC_USER, **SQL_DIC_USEROPENID}) user_rs = con.execute_sql(sql, {"appid": app_id, "oid": openid}) if user_rs and user_rs[0]: user_obj = user_rs[0] else: ret.msg = '用户信息不存在' if user_obj: # 记录登录日志 add_visitor(get_ip(req), apps.get_app_config('app_mf').name, 'login', user_obj.id) # 组织可见的user_info user_info = {"id": user_obj.id, "username": user_obj.userName} # 生成登录token # 存入缓存格式: token:user_info token_tmp = create_token(user_info, expt=-1) # 存入缓存格式: appid+openid:token r.set_one(app_id + openid, token_tmp) ret.data = {"token": token_tmp, "userInfo": user_info} else: ret.data = {} return JsonResponse(ret.to_dic())
def log_in(req, code_way, sid): """ log_in :param req: :param code_way: smscode.短信验证码;piccode.图形验证码 :param sid: 验证码会话sid :return: """ ret = ResModel() ret.msg = req_invalid_check(req) if ret.msg: # 请求合法性校验不通过 ret.code = ret.ResCode.fail return JsonResponse(ret.to_dic()) # 获取redis缓存数据 r = RedisCtrl() verify_code = r.get_one(REDIS_KEY_PRE_SID + sid) if not verify_code: ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) # 图形验证码or短信验证码 auth_code = req.POST.get('authCode', '').upper() # 用户账户,若为短信方式,则该字段为手机号;图形验证码的话,该字段可以是account、email、phone user_acc = req.POST.get('userAcc', '') # 密码为为md5加密的值 pwd = req.POST.get('pwd', '').upper() # 是否需校验密码 need_check_pwd = False if code_way == 'piccode': # 登录方式.piccode.图形验证码 # 校验验证码 if (not settings.DEBUG) and (verify_code.upper() != auth_code): # 是否为debug模式,非debug模式,需校验验证码 ret.msg = '验证码错误' return JsonResponse(ret.to_dic()) need_check_pwd = True elif code_way == 'smscode': # 登录方式.smscode.短信验证码 sms_code = r.get_one(REDIS_KEY_PRE_SMSCODE + user_acc) if not sms_code: # 短信验证码不存在 ret.msg = '验证码已过期' return JsonResponse(ret.to_dic()) if (not settings.DEBUG) and (sms_code != auth_code): # 是否为debug模式,非debug模式,需校验验证码 ret.msg = '短信验证码错误' # 记录错误次数,多次失败则需重新请求sid err_cnt = r.get_one(REDIS_KEY_PRE_CODEERR + user_acc) if not err_cnt: err_cnt = 1 r.set_one(REDIS_KEY_PRE_CODEERR + user_acc, str(err_cnt), expt=60 * 5) else: err_cnt = int(err_cnt) + 1 r.set_one(REDIS_KEY_PRE_CODEERR + user_acc, str(err_cnt), expt=60 * 5) if int(err_cnt) >= 10: # 尝试次数大于10次,则需重新发送sms r.del_one(REDIS_KEY_PRE_SMSCODE + user_acc) r.del_one(REDIS_KEY_PRE_CODEERR + user_acc) # 同一个手机号验证码尝试次数过多 flog.warning(f"短信验证码登录时[{user_acc}]用户的短信验证码尝试次数过多") ret.msg = '短信验证码错误,请重新加载' return JsonResponse(ret.to_dic()) else: # 其他code_way,反馈失败 return JsonResponse(ret.to_dic()) # 查询用户信息 with connection() as con: user_rs = con.execute_sql( """select {table1_id}, {table1_account}, {table1_uname}, {table1_pwd}, {table1_salt}, {table1_wx}, {table1_qq}, {table1_phone}, {table1_email} from {table1} where ( {table1_account}=%(user_acc)s or {table1_phone}=%(user_acc)s or {table1_email}=%(user_acc)s)""".format( **SQL_DIC_USER), {"user_acc": user_acc} ) if user_rs and user_rs[0]: user_obj = user_rs[0] # 获取用户角色 role_rs = con.execute_sql( """select a.{tabler_id} as id from {tabler} a, {table3} b where a.{tabler_id}=b.{table3_rid} and b.{table3_uid}=%(uid)s""".format(**{**SQL_DIC_ROLES, **SQL_DIC_USERROLE}), {"uid": user_obj.id}) roles = ','.join([i.id for i in role_rs]) else: # 需校验密码的话,提示语要隐晦一些 ret.msg = '用户名或密码错误' if need_check_pwd else '用户信息不存在' return JsonResponse(ret.to_dic()) if need_check_pwd: # 接下来校验account-pwd 或 phone-pwd 或 email-pwd db_pwd = user_obj.pwdValue or '' db_salt = user_obj.pwdSalt # 密码校验 p = PwdCtrl() if db_pwd.upper() != p.create_md5(src_str=pwd, salt=db_salt): # 密码校验不通过 ret.msg = '用户名或密码错误' return JsonResponse(ret.to_dic()) # 记录登录日志 add_visitor(get_ip(req), apps.get_app_config('app_dr').name, 'login', user_obj.id) # 组织可见的user_info user_info = {"id": user_obj.id, "username": user_obj.userName, "account": user_obj.account} # 生成登录token # redis中额外放入元素roles等;但是不必返回前端 user_info_redis = {**user_info} user_info_redis["roles"] = roles token = create_token(user_info_redis) ret.data = {"token": token, "referer": req.META.get("HTTP_REFERER"), "userInfo": user_info} ret.msg = f'欢迎{user_obj.userName}' ret.code = ret.ResCode.succ return JsonResponse(ret.to_dic())