def timer_job(job_task_id, job_task_uuid, job_to): try: lock.acquire() global shared shared.pop(job_task_uuid) # 确保重复的uuid,DB里面的状态只变更一次. finally: lock.release() logging.info("I'm changing DB[%s, %s] to [TIMEOUT-ERR]..." % (job_task_uuid, utc_8_now())) FSM.write_db(job_task_id, utc_8_now(), 'TIMEOUT-ERR', 'TIMEOUT after [%s] minutes.' % job_to) logging.info("--[Timer]My Thread--: %s, shared: %s" % (threading.current_thread(), shared)) logging.info("--[Timer]Active threads count--: %s" % threading.active_count())
def push_validated(**kw): # 参数合法性检查. 如果不合法,直接报错. kw['tel'] = "" is_valid_kw(Flow, **kw) # 1. 重复的运单, 不能通过 expr_num = kw['expr_num'] f = Flow.find_first('*', 'where expr_num=?', expr_num) if f: raise ValueError( 'Flow with expr_num=[%s] as validated already exists.' % expr_num) # 从man_id拿tel man_id = kw['man_id'] man = Man.objects(id=man_id).first() if not man: raise ValueError("No such man=[%s]." % man_id) kw['tel'] = man.tel if man.tel else "" # 2. 记录流水 kw['create_time'] = utc_8_now() kw['update_time'] = utc_8_now() kw['cash'] = round(Decimal(kw['cash']), 1) flow = Flow(**kw) # 如果是测试人员,在流水的remark里面记录一下. if man.name and safe_str(man.name).find('测试'.encode('utf-8')) != -1: flow.remark = '测试' elif len(man.accounts) > 0 and safe_str(man.accounts[0]['name']).find( '测试'.encode('utf-8')) != -1: flow.remark = '测试' flow.insert() # 3. 增加可提现: 如果是第一次审核通过, 创建flow_statistics记录. stat = Statistics.find_first('*', 'where man_id=?', man_id) if not stat: stat = Statistics(man_id=man_id, can_cash=kw['cash'], finance=0, paid=0, decline=0) # 如果是测试人员,在统计表的man_name里面记录一下. if man.name and safe_str(man.name).find( '测试'.encode('utf-8')) != -1: stat.man_name = man.name elif len(man.accounts) > 0 and safe_str( man.accounts[0]['name']).find('测试'.encode('utf-8')) != -1: stat.man_name = man.accounts[0]['name'] stat.insert() else: stat.can_cash = round( (Decimal(stat.can_cash) + Decimal(kw["cash"])), 1) # 计算[可提现] stat.update()
def create(**kw): # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(OrderStateLog, **kw) now = utc_8_now() kw['state_change_time'] = kw.get('state_change_time', now) task_state = OrderStateLog(**kw) task_state.insert()
def update_state(cls, **kw): policy_id, state = int(kw.get("task_id", 0)), str(kw.get("state", "")).upper() task_uuid, to, info = str(kw.get("task_uuid", "")), float( kw.get("to_minute", .0)), str(kw.get("info", "")) logging.info("--[ENTRY]Active threads count--: %s" % threading.active_count()) start_time = utc_8_now() to = to if 0 < to < 31 else 5 # 默认5分钟超时 # 简单判断policy_id是否存在 _p = HotOrderLogic.find_by('id, policy_name', 'where id=?', '', policy_id) if not _p and state != "RESET": raise AttributeError( "Policy with id=[{}] not found.".format(policy_id)) # 根据想要更新的状态判断逻辑 fp = { 'STARTED': lambda x: cls.started(policy_id, _p[0].policy_name, task_uuid, start_time, x, to), 'OK': lambda x: cls.ended( policy_id, task_uuid, start_time, x, o_info='OK'), 'ERR': lambda x: cls.ended(policy_id, task_uuid, start_time, 'RUNTIME-ERR', info), 'RESET': lambda x: cls.reset(x) } fp[state](state)
def create(**kw): # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(ShopFSMLog, **kw) now = utc_8_now() kw['create_time'] = kw.get('create_time', now) shop_fsm_log = ShopFSMLog(**kw) shop_fsm_log.insert()
def refund(**kw): # todo: 不要从shop_id拿name, tel, 商户信息改从参数传入 shop_id = kw['shop_id'] shop = Shop.objects(id=shop_id).first() if not shop: raise ValueError("No such shop=[%s]." % shop_id) kw['shop_name'] = shop.name if shop.name else "" kw['shop_tel'] = shop.tel if shop.tel else "" kw['type'] = TRANSACT_TYPE.REFUND kw['cash'] = round(Decimal(kw['cash']), 2) cash = kw['cash'] kw['create_time'] = utc_8_now() # 1. 增加余额; 减少消费; stat = Statistics.find_first('*', 'where shop_id=?', shop_id) if not stat: raise ValueError( "Trying to refund non-existed/haven't topped up shop with id=[%s], please register or top up first." % shop_id) else: stat.balance = round(Decimal(stat.balance) + Decimal(cash), 2) stat.expense = round(Decimal(stat.expense) - Decimal(cash), 2) if stat.expense < 0: raise ValueError( "Shop[%s] will have minus expense after refund of [%s]." % (shop_id, cash)) kw['balance'] = stat.balance stat.update() # 2. 记录流水: 流水中记入这次操作后的balance flow = Flow(**kw) flow.insert() return flow.transact_num
def decline(**kw): # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(Flow, is_update=True, **kw) transact_num = kw['transact_num'] # todo lock on man_id flow = Flow.find_first('*', 'where transact_num=?', transact_num) if not flow: raise ValueError("No cash flow found for transact_num=[%s]." % transact_num) if flow.type != CASH_FLOW.APPLY_WITHDRAW: raise ValueError("Cash flow for transact_num=[%s] has been %s." % (transact_num, flow.type)) man_id = flow.man_id # 检查cash, type: flow.cash == cash? flow.type == APPLY_WITHDRAW? if round(Decimal(flow.cash), 1) != round(Decimal(kw['cash']), 1): raise ValueError( "Cash flow for transact_num=[%s] cash amount=[%s], you are trying to decline [%s]." % (transact_num, flow.cash, kw['cash'])) flow.type = kw['type'] # 将指定[transact_num]的那条记录的type改成[DECLINE] flow.operator_id = kw['operator_id'] # 将指定[transact_num]的那条记录新增操作人 flow.remark = kw.get('remark', '') flow.update_time = utc_8_now() # 将指定[transact_num]的那条记录新增操作时间 flow.update() cash = flow.cash stat = Statistics.find_first('*', 'where man_id=?', man_id) if not stat: raise ValueError( "No flow_statistics record found for man_id=[%s]." % man_id) stat.finance = round((Decimal(stat.finance) - Decimal(cash)), 1) # 计算[财务待处理] stat.decline = round((Decimal(stat.decline) + Decimal(cash)), 1) # 计算[财务已拒绝] stat.update()
def create(**kw): # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(ManFSMLog, **kw) now = utc_8_now() kw['create_time'] = kw.get('create_time', now) deliveryman_fsm_log = ManFSMLog(**kw) deliveryman_fsm_log.insert()
def api_check_notify_reset(is_notify): def long_task(t_receivers, t_ids, t_names, t_states): send_mail(t_receivers, '(线上)定时任务运行错误', '出错任务id=[%s],\n 任务名=[%s],\n 任务状态=[%s]\n' % (t_ids, t_names, t_states)) # 每天早上10点, 判断凌晨的定时任务有没有跑/跑成功. 判断完, 1.发邮件,2.RESET. # 1.拿policy表里所有deleted不为1的id,state; 2.取出所有state不为OK的err_policies, 如果err_policies不为空, 发邮件; 3.RESET. all_policies = PolicyLogic.find_by('id, policy_name, state, date(update_time)', '', '') err_policies = [] for p in all_policies: if p['state'] != 'OK': err_policies.append(p) elif p['state'] == 'OK' and p['date(update_time)'] != utc_8_now(is_date=True): err_policies.append(p) if is_notify == '1': if err_policies: # 发邮件 receivers = ['*****@*****.**','*****@*****.**'] ids = ",".join([unicode(x.id).encode('utf-8') for x in err_policies]) names = ",".join([x.policy_name.encode('utf-8') for x in err_policies]) states = ",".join([x.state.encode('utf-8') for x in err_policies]) # 创建一个定时器, 1秒hook到发警报邮件的任务函数(因为发邮件时间太长,接口不该等在那里) t = Timer(1.0, long_task, args=[receivers, ids, names, states]) # 开启定时器 t.start() else: return err_policies else: # RESET FSM.reset("RESET") return err_policies
def api_hot_order_check_notify_reset(): def long_task(t_receivers, t_ids, t_names, t_states): send_mail( t_receivers, '(线上)定时任务运行错误', '出错任务id=[%s],\n 任务名=[%s],\n 任务状态=[%s]\n' % (t_ids, t_names, t_states)) # 每天早上10点, 判断凌晨的定时任务有没有跑/跑成功. 判断完, 1.发邮件,2.RESET. # 1.拿hot_order表里所有deleted不为1的id,state; 2.取出所有state不为OK的err_policies, 如果err_policies不为空, 发邮件; 3.RESET. all_policies = HotOrderLogic.find_by( 'id, hot_order_name, state, date(update_time)', '', '') err_policies = [] for p in all_policies: if p['state'] != 'OK': err_policies.append(p) elif p['state'] == 'OK' and p['date(update_time)'] != utc_8_now( is_date=True): err_policies.append(p) if err_policies: # 发邮件 receivers = ['*****@*****.**'] ids = ",".join([unicode(x.id).encode('utf-8') for x in err_policies]) names = ",".join( [x.hot_order_name.encode('utf-8') for x in err_policies]) states = ",".join([x.state.encode('utf-8') for x in err_policies]) # 创建一个定时器, 1秒hook到发警报邮件的任务函数(因为发邮件时间太长,接口不该等在那里) t = Timer(1.0, long_task, args=[receivers, ids, names, states]) # 开启定时器 t.start() # RESET FSM.reset("RESET") return err_policies
def api_hot_order_check_state(hot_order_id): # 简单判断hot_order_id是否存在 _p = HotOrderLogic.find_by('id, hot_order_name, state, date(update_time)', 'where id=?', '', hot_order_id) if not _p: raise AttributeError("HotOrder with id=[{}] not found.".format(hot_order_id)) elif _p[0]['date(update_time)'] != utc_8_now(is_date=True): return "NO_RUN" else: return _p[0]['state']
def api_check_state(policy_id): # 简单判断policy_id是否存在 _p = PolicyLogic.find_by('id, policy_name, state, date(update_time)', 'where id=?', '', policy_id) if not _p: raise AttributeError("Policy with id=[{}] not found.".format(policy_id)) elif _p[0]['date(update_time)'] != utc_8_now(is_date=True): return "NO_RUN" else: return _p[0]['state']
def push_apply_withdraw(**kw): # 参数合法性检查. 如果不合法,直接报错. kw['tel'] = "" is_valid_kw(Flow, **kw) # 从man_id拿tel man_id = kw['man_id'] man = Man.objects(id=man_id).first() man_tel = man.tel kw['tel'] = man_tel if man_tel else "" # 限制1: 如果是系统有效全职,不可提现. ==>暂时通过登录来控制 # 限制2: 限额设为sum(VALIDATED)-sum(APPLY_WITHDRAW) man_id = kw['man_id'] cash = Decimal(kw['cash']) # 1. 先floor提现额度到角, 并判断是否超出提现额度. kw['cash'] = floor(cash * 10) / 10.0 cash = Decimal(str(kw['cash'])) stat = Statistics.find_first('*', 'where man_id=?', man_id) if not stat: raise ValueError("You have no cash to withdraw.") elif stat.can_cash <= 0: raise ValueError("You have no cash to withdraw.") elif cash <= 0: raise ValueError("Why apply for zero or minus value cash?") elif cash > stat.can_cash: raise ValueError( "You are not allowed to apply for cash over [%s] yuan, you are applying [%s]." % (stat.can_cash, cash)) # 2. 添加提现记录 kw['create_time'] = utc_8_now() kw['update_time'] = utc_8_now() flow = Flow(**kw) # 如果是测试人员,在流水的remark里面记录一下. if man.name and safe_str(man.name).find('测试'.encode('utf-8')) != -1: flow.remark = '测试' elif len(man.accounts) > 0 and safe_str(man.accounts[0]['name']).find( '测试'.encode('utf-8')) != -1: flow.remark = '测试' flow.insert() # 3. 减少可提现; 增加待财务处理; 更新account_name到man_name stat.can_cash = round((Decimal(stat.can_cash) - cash), 1) # 计算[可提现] stat.finance = round((Decimal(stat.finance) + cash), 1) # 计算[待财务处理] stat.man_name = kw['account_name'] if kw[ 'account_name'] else stat.man_name stat.update()
def api_hot_order_check_state(hot_order_id): # 简单判断hot_order_id是否存在 _p = HotOrderLogic.find_by('id, hot_order_name, state, date(update_time)', 'where id=?', '', hot_order_id) if not _p: raise AttributeError( "HotOrder with id=[{}] not found.".format(hot_order_id)) elif _p[0]['date(update_time)'] != utc_8_now(is_date=True): return "NO_RUN" else: return _p[0]['state']
def gen(): kw = dict() kw["create_time"] = utc_8_now() tn = TrackingNumber(**kw) r = tn.insert() if r == 1: num = TrackingNumber.find_first( 'max(tracking_number) as tracking_number', '') return "%012d" % num else: raise ValueError("Gen tracking number failed.")
def api_check_state(policy_id): # 简单判断policy_id是否存在 _p = PolicyLogic.find_by('id, policy_name, state, date(update_time)', 'where id=?', '', policy_id) if not _p: raise AttributeError( "Policy with id=[{}] not found.".format(policy_id)) elif _p[0]['date(update_time)'] != utc_8_now(is_date=True): return "NO_RUN" else: return _p[0]['state']
def reset(r_state): all_policy = PolicyLogic.find_by("id", "", "limit 0,1000") # 写DB for policy in all_policy: FSM.write_db(policy, utc_8_now(), r_state, "RESET") try: lock.acquire() global shared shared.clear() finally: lock.release()
def create(**kw): kw['state'] = None now = utc_8_now() kw['create_time'] = now kw['update_time'] = now # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(Policy, **kw) # 检查id,policy_name, 如果存在record, 不允许添加 sanity_check = Policy.find_by('id, policy_name', 'where id=? OR policy_name=?', *[kw['id'], kw['policy_name']]) if sanity_check: raise ValueError("Already exist record with id=[%s], policy_name=[%s]." % (sanity_check[0]['id'], sanity_check[0]['policy_name'])) policy = Policy(**kw) policy.insert()
def create(**kw): kw['state'] = None now = utc_8_now() kw['create_time'] = now kw['update_time'] = now # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(HotOrder, **kw) # 检查id,hot_order_name, 如果存在record, 不允许添加 sanity_check = HotOrder.find_by('order_id', 'where order_id=? AND gen_from=?', *[kw['order_id'], kw['gen_from']]) if sanity_check: raise ValueError("Already exist record with id=[%s], hot_order_name=[%s]." % (sanity_check[0]['id'], sanity_check[0]['hot_order_name'])) hot_order = HotOrder(**kw) hot_order.insert()
def snapshot(): # 批量插入之前, 先将已有的当日快照数据删掉 statistic_date = utc_8_now(is_date=True) db.update('delete from `%s` where `statistic_date`=?' % DailyPolicy.__table__, statistic_date) cols = ["policy_name", "policy_content", "start_effect_time", "end_effect_time", "applied_to", "notification", "policy_leader", "state", "create_time", "update_time", "statistic_date"] p_today = PolicyLogic.find_by('*', '', '') data = [] for p in p_today: data.append((p.policy_name, p.policy_content, p.start_effect_time, p.end_effect_time, p.applied_to, p.notification, p.policy_leader, p.state, p.create_time, p.update_time, statistic_date)) if data: db.insert_many(DailyPolicy.__table__, cols, data) return len(data)
def update(hot_order_id, **kw): # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(HotOrder, is_update=True, **kw) # 获取想要的记录 p = HotOrder.get('id', hot_order_id) # 如果找不到这条记录,报错 if not p: raise AttributeError("Could not find in hot_order with [id]=[%s]. So could not update it, either." % hot_order_id) for key_name in kw: if key_name in p: p[key_name] = kw[key_name] now = utc_8_now() p['update_time'] = now p.update()
def update(hot_order_id, **kw): # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(HotOrder, is_update=True, **kw) # 获取想要的记录 p = HotOrder.get('id', hot_order_id) # 如果找不到这条记录,报错 if not p: raise AttributeError( "Could not find in hot_order with [id]=[%s]. So could not update it, either." % hot_order_id) for key_name in kw: if key_name in p: p[key_name] = kw[key_name] now = utc_8_now() p['update_time'] = now p.update()
def transfer_success(**kw): # 输入kw: result, transact_num, trade_no, remark logging.info('transfer_success, kw=%s' % kw) transact_num = kw['transact_num'] # 0. 已经收到过该通知,直接返回; flow = Flow.find_first('*', 'where transact_num=?', transact_num) if flow: logging.info( "Already received notification for transact_num=[%s]." % transact_num) return FlowLogic.MSGS.notify_duplicated_success # 1. 记录flow_top_up.result; top_up_flow = TopUp.find_first('*', 'where transact_num=?', transact_num) top_up_flow.result = kw['result'] top_up_flow.trade_no = kw['trade_no'] top_up_flow.update() kw['shop_id'] = top_up_flow.shop_id # 根据flow_top_up, 从shop_id拿name, tel, 不会真正去查商户数据库 shop_id = top_up_flow.shop_id kw['shop_name'] = top_up_flow.shop_name kw['shop_tel'] = top_up_flow.shop_tel kw['create_time'] = utc_8_now() kw['cash'] = round(Decimal(top_up_flow.cash), 2) kw['type'] = TRANSACT_TYPE.PAY cash = kw['cash'] # 2. 增加消费; stat = Statistics.find_first('*', 'where shop_id=?', shop_id) if not stat: stat = Statistics(shop_id=shop_id, shop_name=kw['shop_name'], expense=cash) kw['balance'] = 0 stat.insert() else: stat.expense = round((Decimal(stat.expense) + Decimal(cash)), 2) # 计算[消费] kw['balance'] = stat.balance stat.update() # 3. 记录流水: 流水中还要记入这次操作后的balance. flow = Flow(**kw) flow.insert() return FlowLogic.MSGS.notify_first_success
def create(**kw): kw['state'] = None now = utc_8_now() kw['create_time'] = now kw['update_time'] = now # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(Policy, **kw) # 检查id,policy_name, 如果存在record, 不允许添加 sanity_check = Policy.find_by('id, policy_name', 'where id=? OR policy_name=?', *[kw['id'], kw['policy_name']]) if sanity_check: raise ValueError( "Already exist record with id=[%s], policy_name=[%s]." % (sanity_check[0]['id'], sanity_check[0]['policy_name'])) policy = Policy(**kw) policy.insert()
def create(**kw): kw['state'] = None now = utc_8_now() kw['create_time'] = now kw['update_time'] = now # 参数合法性检查. 如果不合法,直接报错. is_valid_kw(HotOrder, **kw) # 检查id,hot_order_name, 如果存在record, 不允许添加 sanity_check = HotOrder.find_by('order_id', 'where order_id=? AND gen_from=?', *[kw['order_id'], kw['gen_from']]) if sanity_check: raise ValueError( "Already exist record with id=[%s], hot_order_name=[%s]." % (sanity_check[0]['id'], sanity_check[0]['hot_order_name'])) hot_order = HotOrder(**kw) hot_order.insert()
def update_state(cls, **kw): policy_id, state = int(kw.get("task_id", 0)), str(kw.get("state", "")).upper() task_uuid, to, info = str(kw.get("task_uuid","")), float(kw.get("to_minute", .0)), str(kw.get("info", "")) logging.info("--[ENTRY]Active threads count--: %s" % threading.active_count()) start_time = utc_8_now() to = to if 0 < to < 31 else 5 # 默认5分钟超时 # 简单判断policy_id是否存在 _p = PolicyLogic.find_by('id, policy_name', 'where id=?', '', policy_id) if not _p and state != "RESET": raise AttributeError("Policy with id=[{}] not found.".format(policy_id)) # 根据想要更新的状态判断逻辑 fp = { 'STARTED': lambda x: cls.started(policy_id, _p[0].policy_name, task_uuid, start_time, x, to), 'OK': lambda x: cls.ended(policy_id, task_uuid, start_time, x, o_info='OK'), 'ERR': lambda x: cls.ended(policy_id, task_uuid, start_time, 'RUNTIME-ERR', info), 'RESET': lambda x: cls.reset(x) } fp[state](state)
def api_working_relation_bind_manager(): # 输入: code=>从redis取到manager_id, man_id kw = ctx.request.input() manager_id = redis_client.get(kw.code) if not manager_id: raise ValueError("绑定工作关系失败:无效二维码.") manager = Man.objects(id=manager_id).first() man = Man.objects(id=kw.man_id).first() err_str = "Bind man[%s][%s] for manager[%s][%s] failed." % ( kw.man_id, man.name, manager_id, manager.name) # 检查从属关系 if not man or not manager: raise ValueError("绑定工作关系失败:找不到相关人员.") if man.my_manager: logging.error(err_str) raise ValueError("绑定工作关系失败:您已绑定过.") if Man.objects(my_man__id=kw.man_id).first(): logging.error(err_str) raise ValueError("绑定工作关系失败:重复绑定.") # 我是小弟: now = utc_8_now(ret=str('datetime')) one_man = dict(id=kw.man_id, name=man.name, tel=man.tel, bind_time=now) one_manager = dict(id=manager_id, name=manager.name, tel=manager.tel, bind_time=now) # 1. 将小弟加入manager的那个Document里面 result = Man.objects(id=manager_id).update_one(add_to_set__my_man=one_man, full_result=True) if result['nModified'] == 0: logging.error(err_str) raise ValueError("绑定工作关系失败.") # 2. 将小弟Document加入my_manager result = Man.objects(id=kw.man_id).update_one(set__my_manager=one_manager, full_result=True) if result['nModified'] == 0: Man.objects(id=kw.manager_id).update_one(pull__my_man=one_man) logging.error(err_str) raise ValueError("绑定工作关系失败.")
def snapshot(): # 批量插入之前, 先将已有的当日快照数据删掉 statistic_date = utc_8_now(is_date=True) db.update( 'delete from `%s` where `statistic_date`=?' % DailyPolicy.__table__, statistic_date) cols = [ "policy_name", "policy_content", "start_effect_time", "end_effect_time", "applied_to", "notification", "policy_leader", "state", "create_time", "update_time", "statistic_date" ] p_today = PolicyLogic.find_by('*', '', '') data = [] for p in p_today: data.append((p.policy_name, p.policy_content, p.start_effect_time, p.end_effect_time, p.applied_to, p.notification, p.policy_leader, p.state, p.create_time, p.update_time, statistic_date)) if data: db.insert_many(DailyPolicy.__table__, cols, data) return len(data)
def update_status(cls, operator_type, shop, event, current_status=None, **kwargs): """ 更新对象的状态 :param operator_type: 'OUTSIDE'/'FE_INSIDE' :param shop: Shop 对象 :param current_status: 当前状态, 如果为None就拿obj的status字段 :param event: 派件员事件类型 :param kwargs: 目前支持: operator_id: 操作人id remark: 操作备注 :return: obj 或 None, None表示出错 """ if current_status is None: current_status = shop.status if shop.status else cls.STATUS_INIT next_state = cls.get_next_state(operator_type, current_status, event) next_status = next_state['next'] if next_state else None if operator_type == 'FE_INSIDE': # ===> 上帝操作!!! <=== if event == cls.EVENT_RESET: next_status = cls.STATUS_INIT # ===> 拉黑操作!!! <=== elif event == cls.EVENT_BAN: next_status = cls.STATUS_BANNED # ===> 修改资料!!! <=== elif event == cls.EVENT_ALTER_INFO: next_status = current_status # 日志 debug_str = 'shop_id[%s][%s]: from [%s] to [%s], event[%s].' % ( shop.id, shop.name, current_status, next_status, event) logging.info(debug_str) if next_status else logging.warning(debug_str) if next_status: # 更新状态 from_status = current_status kwargs['status'] = next_status # 过滤掉不需要的字段 kw = ShopLogic.filter_shop(kwargs, excludes=('shop_id', 'password'), includes=('fee__fh', 'fee__ps', 'fee__fh_base')) shop.modify(**kw) shop.reload() # 事件记录 fsm_log = dict(shop_id=str(shop.pk), shop_name=shop.name, from_status=from_status, to_status=next_status, event=event, operator_type=operator_type, operator_id=kwargs.get('operator_id', ''), remark=kwargs.get('remark', None), create_time=utc_8_now(ret='datetime')) ShopFSMLogLogic.create(**fsm_log) # 判断是否要发送短信提醒: 有remark的话,添加到文案中. if next_state and 'send_sms' in next_state: if kwargs.get('remark'): msg = next_state['send_sms'].format(remark=', 理由: %s。' % kwargs['remark']) else: msg = next_state['send_sms'] async_send_sms(shop.tel, msg=msg, sms_type=SMS_TYPE_NORMAL) return shop else: return None
def create(**kw): is_valid_kw(TopUp, **kw) kw['create_time'] = utc_8_now() tu = TopUp(**kw) tu.insert()
def api_deliveryman_login(): """ @api {get} /deliveryman/login?man_id=&password= 登录 @apiDescription 风先生派件员登录成功则返回token,失败则报错. @apiName api_deliveryman_login @apiGroup man @apiParam {string(11)} [man_id] 派件员工号, 如 7748657. @apiParam {string(11)} [tel] 派件员手机号, 如 150687929321. @apiParam {string(32)} password 派件员密码hash(如果是工号+密码登录), 验证码(如果是手机号+验证码登录). @apiParamExample {json} 请求url示例: /deliveryman/login?man_id=7740959&password=0192023a7bbd73250516f069df18b500 OR /deliveryman/login?tel=150687929321&password=123456 @apiSuccessExample {json} 手机号验证码登录成功示例: HTTP/1.1 200 OK { "tel": "150687929321", "token": "36dc92e290f334aaa96466d3ee9b9efa" } @apiSuccessExample {json} 工号密码登录成功示例: HTTP/1.1 200 OK { "man_id": "7740959", "token": "36dc92e290f334aaa96466d3ee9b9efa" } @apiErrorExample {json} 失败示例: HTTP/1.1 400 ValueError { "message": "No such deliveryman=[774095999]." } @apiErrorExample {json} 失败示例: HTTP/1.1 400 ValueError { "message": "Password validation for [7740959]=[012023a7bbd73250516f069df18b500] failed." } """ allowed_jd = {'parttime', 'city_driver', 'area_manager'} def set_token(inner_who, inner_role='man'): token = hashlib.md5('%s%s' % (inner_who, utc_8_now())).hexdigest() key = key_man_token.format(role=inner_role, content=token) # 插入token到redis中, 30天有效期: get token:fe11ad907e2fa779ed2f363ef589d3f9 => 7740959 redis_client.setex(key, inner_who, 30 * 24 * 3600) return token params = ctx.request.input() tel = str(params.get("tel", "")).strip() password_or_sms_code = str(params.password).strip() role = str(params.get("role", "")).strip() # ==> 首先检查是不是免密码[优先级为: 免密码>手机] if not tel: logging.error("Should provide me with [tel] in params%s." % params) raise ValueError("需要提供手机号登录.") # 存放: 免密码名单和token(30天) # 登录成功: smembers no_password => set(7740959,...); sismember(key_login, man_id) elif redis_client.sismember(key_no_password, tel): # 根据电话找人员记录 man = Man.objects(tel=tel).first() man_id = str(man.pk) content = set_token(man_id) jd = man.job_description[ 0] if man.job_description and man.job_description[ 0] in allowed_jd else 'parttime' return dict(token=content, man_id=man_id, tel=tel, jd=jd) # ==> 职工登录: 手机号+密码 if role: password = password_or_sms_code staff = Staff.objects(tel=tel).first() # 如果此人不存在,直接报错 if not staff: # todo 删除我,改成报错. staff = Staff(tel=tel, password=hashlib.md5('123456').hexdigest(), create_time=utc_8_now(ret='datetime')).save() content = set_token(tel, inner_role='staff') return dict(token=content, man_id=str(staff.pk)) # raise ValueError("No such staff with tel=[%s]." % tel) # 登录成功: 密码与数据库中值匹配 staff_id = str(staff.pk) password_in_db = staff.password if password == password_in_db: content = set_token(tel, inner_role='staff') return dict(token=content, man_id=staff_id) # 登录失败 else: logging.warn( "Password validation for [%s]=[%s] failed, expected[%s]." % (tel, password, password_in_db)) raise ValueError('登录名或密码错误.') # ==> 派件员登录: 手机号+验证码 if tel: sms_code = password_or_sms_code sms_key = key_sms_code.format(tel=tel) # 登录成功: 验证码匹配 get sms:code:13245678901 => 123456 sms_code_in_redis = redis_client.get(sms_key) if sms_code_in_redis == sms_code: # 根据电话找人员记录 man = Man.objects(tel=tel).first() # 取header里面的app-name app_name = ctx.request.header('app-name') # 无记录人员: 记录派件员到mongodb: status=ManFSM.STATUS_INIT, job_description=[app-name] if not man: jd = [app_name] if app_name else [] man = Man(tel=tel, job_description=jd, create_time=utc_8_now(ret="datetime")).save() # ===== 注册风信账户 ===== http_client = HTTPClient() http_client.fetch(tools_lib.windchat.account.req_create( account_type=tools_lib.windchat.conf.ACCOUNT_TYPE_MAN, account_id=str(man.id)), raise_error=False) # 有记录人员: else: jd = man.job_description jd = set(jd) if isinstance(jd, list) else set() if app_name: jd.add(app_name) man.job_description = list(jd) man.save() man_id = str(man.pk) content = set_token(man_id) jd = man.job_description[ 0] if man.job_description and man.job_description[ 0] in allowed_jd else 'parttime' logging.info('[%s][%s][%s]登录成功.' % (man.name, tel, jd)) return dict(token=content, man_id=man_id, tel=tel, jd=jd) # 登录失败 else: logging.warn( "SMS code validation for [%s]=[%s] failed, expected[%s]." % (tel, sms_code, sms_code_in_redis)) raise ValueError("验证码不匹配.若您获取过多次验证码,请输入最新一条短信的验证码")
def set_token(inner_who, inner_role='man'): token = hashlib.md5('%s%s' % (inner_who, utc_8_now())).hexdigest() key = key_man_token.format(role=inner_role, content=token) # 插入token到redis中, 30天有效期: get token:fe11ad907e2fa779ed2f363ef589d3f9 => 7740959 redis_client.setex(key, inner_who, 30 * 24 * 3600) return token
def update_status(cls, operator_type, man, event, current_status=None, **kwargs): """ 更新对象的状态 :param operator_type: 'APP'/'FE' :param man: Man 对象 :param current_status: 当前状态, 如果为None就拿obj的status字段 :param event: 派件员事件类型 :param kwargs: 目前支持: operator_id: 操作人id remark: 操作备注 :return: obj 或 None, None表示出错 """ if current_status is None: current_status = man.status if man.status else cls.STATUS_INIT # 构造传入状态机本身的参数 kw = { 'man_id': man.id, } next_state = cls.get_next_state(operator_type, current_status, event, **kw) next_status = next_state['next'] if next_state else None if operator_type == 'FE': # ===> 上帝操作!!! <=== if event == cls.EVENT_RESET: next_status = cls.STATUS_INIT # ===> 拉黑操作!!! <=== elif event == cls.EVENT_BAN: next_status = cls.STATUS_BANNED # ===> 修改资料!!! <=== elif event == cls.EVENT_COMPLETE_INFO: next_status = current_status # 日志 debug_str = 'man_id[%s][%s]: from [%s] to [%s], event[%s].' % ( man.id, man.name, current_status, next_status, event) logging.info(debug_str) if next_status else logging.warning(debug_str) if next_status: # 更新状态 from_status = current_status kwargs['status'] = next_status kw = ManLogic.filter_man(kwargs) man.modify(**kw) # 事件记录 fsm_log = dict(man_id=str(man.pk), man_name=man.name, from_status=from_status, to_status=next_status, event=event, operator_type=operator_type, operator_id=kwargs.get('operator_id', ''), remark=kwargs.get('remark', None), create_time=utc_8_now(ret='datetime')) ManFSMLogLogic.create(**fsm_log) # 判断是否要发送短信提醒: 有remark的话,添加到文案中. if next_state and 'send_sms' in next_state: if kwargs.get('remark'): msg = next_state['send_sms'].format(remark=', 理由: %s。' % kwargs['remark']) else: msg = next_state['send_sms'] async_send_sms(man.tel, msg=msg, sms_type=SMS_TYPE_NORMAL) return man else: return None
def set_token(inner_who): token = hashlib.md5('%s%s' % (inner_who, utc_8_now())).hexdigest() key = key_shop_token.format(content=token) # 插入token到redis中, 7天有效期: get shop:token:fe11ad907e2fa779ed2f363ef589d3f9 => 7740959 redis_client.setex(key, inner_who, 7 * 24 * 3600) return token