Пример #1
0
 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())
Пример #2
0
    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()
Пример #3
0
 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()
Пример #4
0
    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)
Пример #5
0
 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()
Пример #6
0
    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
Пример #7
0
 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()
Пример #8
0
    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()
Пример #9
0
 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()
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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']
Пример #13
0
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']
Пример #14
0
 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()
Пример #15
0
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']
Пример #16
0
 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.")
Пример #17
0
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']
Пример #18
0
 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()
Пример #19
0
 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()
Пример #20
0
 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()
Пример #21
0
    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)
Пример #22
0
 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()
Пример #23
0
 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()
Пример #24
0
    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
Пример #25
0
 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()
Пример #26
0
 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()
Пример #27
0
    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)
Пример #28
0
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("绑定工作关系失败.")
Пример #29
0
    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)
Пример #30
0
    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
Пример #31
0
 def create(**kw):
     is_valid_kw(TopUp, **kw)
     kw['create_time'] = utc_8_now()
     tu = TopUp(**kw)
     tu.insert()
Пример #32
0
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("验证码不匹配.若您获取过多次验证码,请输入最新一条短信的验证码")
Пример #33
0
 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
Пример #34
0
    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
Пример #35
0
 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