Ejemplo n.º 1
0
    def test_channel_config_model(self):
        data = dict(
            channel_enum=ChannelConfigEnum.CHANNEL_1001,
            fee=Decimal("2.1"),
            fee_type=PaymentFeeTypeEnum.PERCENT_PER_ORDER,
            limit_per_min=Decimal("100.0"),
            limit_per_max=Decimal("1000.0"),
            limit_day_max=Decimal("500000.0"),
            trade_begin_hour=9,
            trade_begin_minute=0,
            trade_end_hour=20,
            trade_end_minute=30,
            settlement_type=SettleTypeEnum.D0,
            maintain_begin=DateTimeKit.str_to_datetime("2016-10-01 09:30", DateTimeFormatEnum.MINUTES_FORMAT),
            maintain_end=DateTimeKit.str_to_datetime("2016-10-02 21:30", DateTimeFormatEnum.MINUTES_FORMAT),
            priority=1
        )

        self.__update_channel(data, 1, 1)

        data['fee'] = Decimal("3.55")
        data['priority'] = 10
        data['maintain_begin'] = DateTimeKit.str_to_datetime("2016-10-01 12:30", DateTimeFormatEnum.MINUTES_FORMAT)
        self.__update_channel(data, 1, 2)

        data['priority'] = -100
        data['channel_enum'] = ChannelConfigEnum.CHANNEL_1002
        self.__update_channel(data, 2, 3)
Ejemplo n.º 2
0
 def get_clean_date(cls):
     """
     获取清理日期
     :return:
     """
     return DateTimeKit.get_cur_date() - DateTimeKit.time_delta(
         days=cls.HOT_DAYS)
Ejemplo n.º 3
0
    def get(self):
        """
        后台管理员操作日志
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message="参数规则:?account=panda&date=20190901&export=1"
            ).as_response()

        account = request.args['account']
        if account:
            user = AdminUser.query_user(account=account)
            if not user:
                return ResponseSuccess(message="用户不存在,请检查参数。account:%s" %
                                       account).as_response()

        try:
            date = request.args.get('date')
            if date:
                date = DateTimeKit.str_to_datetime(
                    date, DateTimeFormatEnum.TIGHT_DAY_FORMAT, to_date=True)
            else:
                date = DateTimeKit.get_cur_date()
        except:
            return ResponseSuccess(
                message="请输入有效的查询日期,格式为:20190901").as_response()

        events = AdminLog.query_by_date(date)
        if account:
            events = events.filter_by(account=account)

        rst = list()

        for event in events:
            rst.append(
                dict(
                    create_time=event.create_time,
                    account=event.account,
                    url=event.url,
                    ip=event.ip,
                    module=event.module.desc,
                    model=event.model,
                    model_id=event.model_id,
                    data_before=event.data_before,
                    data_after=event.data_after,
                ))

        rst = sorted(rst, key=lambda x: x['create_time'], reverse=True)
        for x in rst:
            x['create_time'] = DateTimeKit.datetime_to_str(x['create_time'])

        if rst and request.args.get('export'):
            filename = 'admin_log_%s.csv' % DateTimeKit.datetime_to_str(
                date, DateTimeFormatEnum.TIGHT_DAY_FORMAT)
            return CsvKit.send_csv(rst,
                                   filename=filename,
                                   fields=rst[0].keys())

        return ResponseSuccess(bs_data=rst).as_response()
Ejemplo n.º 4
0
 def get_expiration(self):
     """
     计算交易密码错误次数过期时间,过期时间为每天的午夜0点
     :return:
     """
     return DateTimeKit.gen_midnight_timestamp(
     ) - DateTimeKit.get_cur_timestamp()
Ejemplo n.º 5
0
    def check_and_clean(cls, keep_days=7):

        full_path = os.path.join(BASEDIR, log_path)

        delete_files = list()

        for name in os.listdir(full_path):
            # print(name)
            if log_prefix not in name:
                continue

            try:
                date_str = name.split('.')[-1]
                date = DateTimeKit.str_to_datetime(
                    date_str, DateTimeFormatEnum.DAY_FORMAT)
            except:
                continue

            delta_days = (DateTimeKit.get_cur_datetime() - date).days
            # print(delta_days, keep_days)
            if delta_days < keep_days:
                print('keep file: ', name)
                continue

            delete_files.append(name)

        for name in delete_files:
            file = os.path.join(full_path, name)
            print('removed ', file)
            os.remove(file)
Ejemplo n.º 6
0
 def covert_data_to_dict(cls, value):
     data = dict()
     for k, v in value.items():
         if isinstance(v, Enum):
             v = v.to_dict()
         elif isinstance(v, Decimal):
             v = str(v)
         elif isinstance(v, (datetime.datetime, datetime.date)):
             v = DateTimeKit.datetime_to_timestamp(v)
         elif isinstance(v, dict):
             v = cls.covert_data_to_dict(v)
         elif isinstance(v, list):
             v_list = list()
             for x in v:
                 if isinstance(x, Enum):
                     x = x.to_dict()
                 elif isinstance(x, Decimal):
                     x = str(x)
                 elif isinstance(x, (datetime.datetime, datetime.date)):
                     x = DateTimeKit.datetime_to_timestamp(v)
                 elif isinstance(x, dict):
                     x = cls.covert_data_to_dict(x)
                 v_list.append(x)
             v = v_list
         data[k] = v
     return data
Ejemplo n.º 7
0
 def count_all_records(cls):
     merchant = MerchantEnum.TEST
     create_time = DateTimeKit.get_cur_datetime()
     begin, end = DateTimeKit.get_month_begin_end(create_time.year,
                                                  create_time.month)
     return cls.query_by_create_time(begin,
                                     end,
                                     merchant=merchant,
                                     date=create_time).count()
Ejemplo n.º 8
0
 def query_by_create_time(cls, begin_time, end_time, **kwargs):
     """
     根据时间查询数据,包含 begin_time/end_time 边界值
     :param begin_time:
     :param end_time:
     :return: 返回查询对象
     """
     begin_time = DateTimeKit.datetime_to_timestamp(begin_time)
     end_time = DateTimeKit.datetime_to_timestamp(end_time)
     return cls.query.filter(cls._create_time.between(begin_time, end_time))
Ejemplo n.º 9
0
 def validate_end_datetime(self, value):
     if value.data == '':
         self.end_datetime.data = DateTimeKit.get_day_begin_end(
             DateTimeKit.get_cur_date())[1]
     else:
         try:
             self.end_datetime.data = DateTimeKit.str_to_datetime(
                 value.data, DateTimeFormatEnum.SECONDS_FORMAT)
         except Exception as e:
             raise StopValidation('查询日期格式有误')
Ejemplo n.º 10
0
class MonthMix(BaseMix):
    """
    按月分表的模型
    """
    MAX_MONTHS = TABLE_MAX_MONTHS
    __OLDEST_DATE = TABLE_BEGIN_TIME
    TABLE_SUFFIXES = [
        DateTimeKit.datetime_to_str(x, DateTimeFormatEnum.TIGHT_MONTH_FORMAT)
        for x in DateTimeKit.gen_month_range(__OLDEST_DATE, months=MAX_MONTHS)
    ]

    @classmethod
    def is_valid_shard_date(cls, date):
        """
        判断日期是否小于最小的分表日期
        :param date:
        :return:
        """
        if date.year < cls.__OLDEST_DATE.year or (
                date.year == cls.__OLDEST_DATE.year
                and date.month < cls.__OLDEST_DATE.month):
            return False

        return True

    @classmethod
    def _check_required_params(cls, **kwargs):
        """
        必填参数检查
        :param kwargs:
        :return:
        """
        date = kwargs.get('date')

        if not date or not DateTimeKit.is_datetime(date):
            raise ShardParamsException(
                'date is required for cls: %s, kwargs: %s' %
                (cls.__name__, kwargs))

        if not cls.is_valid_shard_date(date):
            raise ShardDateException(
                'sharding date must gte %s, cls: %s, kwargs: %s' %
                (cls.__OLDEST_DATE, cls.__name__, kwargs))

    @classmethod
    def _parse_suffix(cls, *args, **kwargs):
        """
        表后缀
        :param args:
        :param kwargs:
        :return:
        """
        return DateTimeKit.datetime_to_str(
            kwargs['date'], DateTimeFormatEnum.TIGHT_MONTH_FORMAT)
Ejemplo n.º 11
0
    def post(self):
        """
        用户列表
        :return:
        """
        form, error = UserListSelectForm.request_validate()
        if error:
            return error.as_response()

        kwargs = dict()
        if form.phone_number.data:
            phone_number = str(form.phone_number.data)
            if phone_number.find("+") < 0:
                phone_number = "{}{}".format("+", phone_number)
            kwargs['account'] = phone_number

        user_query = User.query.filter_by(**kwargs)
        if form.start_datetime.data:
            user_query = user_query.filter(
                User._create_time >= DateTimeKit.datetime_to_timestamp(
                    form.start_datetime.data))
        if form.end_datetime.data:
            user_query = user_query.filter(
                User._create_time <= DateTimeKit.datetime_to_timestamp(
                    form.end_datetime.data))
        paginate = user_query.paginate(form.page_index.data,
                                       form.page_size.data, False)

        total = paginate.total
        user_lst = paginate.items

        uid_lst = [u.id for u in user_lst]
        uid_merchant = UserBalance.query.filter(
            UserBalance.id.in_(uid_lst)).all()
        mer_bl_uid = {
            uid.id: dict(balance=uid.real_balance, merchant=uid.merchant)
            for uid in uid_merchant
        }

        data = [
            dict(user_id=u.id,
                 phone_number=PhoneNumberParser.hide_number(u.account),
                 type='测试用户' if u.is_test_user else "普通用户",
                 source=mer_bl_uid[u.id]['merchant'].name,
                 available_bl=mer_bl_uid[u.id]['balance'],
                 register_datetime=u.str_create_time,
                 state=u.state.name) for u in user_lst
        ]

        return UserListResult(
            bs_data=dict(entries=data, total=total)).as_response()
Ejemplo n.º 12
0
    def query_by_create_time(cls, begin_time, end_time, *args, **kwargs):
        """
        根据时间查询数据,包含begin_time, end_time,[begin_time, end_time]
        :param begin_time:
        :param end_time:
        :return: 返回查询对象
        """
        begin_ts = DateTimeKit.datetime_to_timestamp(begin_time)
        end_ts = DateTimeKit.datetime_to_timestamp(end_time)

        model_cls = kwargs.get('model_cls') or cls.get_model_cls(
            *args, **kwargs)
        return model_cls.query.filter(model_cls._create_time >= begin_ts,
                                      model_cls._create_time <= end_ts)
Ejemplo n.º 13
0
    def create_order(cls):
        merchant = MerchantEnum.TEST
        order_id = OrderTstGid.generate_order_id()
        create_time = DateTimeKit.get_cur_datetime()

        fields = dict(
            uid=0,
            create_time=create_time,
            update_time=create_time,
            order_id=order_id,
            amount=Decimal("234142.33"),
            mch_tx_id=OrderUtils.generate_mch_tx_id(order_id),
            sys_tx_id=OrderUtils.generate_sys_tx_id(order_id),
            source=OrderSourceEnum.MANUALLY,
            state=OrderStateEnum.INIT,
            op_account='test',
            pay_method=PayMethodEnum.ZHIFUBAO_SAOMA,
            notify_url="https://google.com",
            result_url="https://google.com",
            extra=json.dumps(dict(x=1, y=2, z=3)),
        )

        rst = cls.add_model(fields,
                            merchant=merchant,
                            date=create_time,
                            commit=True)
        return rst
Ejemplo n.º 14
0
 def validate_done_end_time(self, value):
     try:
         if value.data:
             self.done_end_time.data = DateTimeKit.str_to_datetime(
                 value.data, DateTimeFormatEnum.SECONDS_FORMAT)
     except Exception as e:
         raise StopValidation("时间格式不对 精确到秒")
Ejemplo n.º 15
0
 def validate_maintain_end(self, value):
     try:
         if value.data:
             self.maintain_end.data = DateTimeKit.str_to_datetime(
                 value.data)
     except Exception as e:
         raise StopValidation("无效的时间格式")
Ejemplo n.º 16
0
    def post(self):
        """
        获取用户交易历史记录
        """
        form, error = UserOrderSelectForm().request_validate()
        if error:
            return error.as_response()

        uid = g.user.uid
        merchant = g.user.merchant

        try:
            begin_time, end_time = DateTimeKit.get_month_begin_end(
                int(form.year.data), int(form.mouth.data))
        except Exception as e:
            return SelectDepositWithdrawDateError().as_response()

        if not MerchantMonthMix.is_valid_shard_date(begin_time):
            # 查询的时间太早,没有数据,直接返回空列表
            return ResponseOrderEntryList(bs_data=dict(
                order_entry_list=[], order_entry_total=0)).as_response()

        order_entry_list, order_entry_total = TransactionListHelper.get_transaction_list(
            form.payment_type.data, uid, merchant, begin_time, end_time,
            TRANSACTION_PAGE_SIZE, form.page_index.data)

        return ResponseOrderEntryList(
            bs_data=dict(order_entry_list=order_entry_list,
                         order_entry_total=order_entry_total)).as_response()
Ejemplo n.º 17
0
    def query_one(cls, query_fields: dict, *args, **kwargs):
        """
        查询模型
        :param query_fields:
        :param args:
        :param kwargs:
        :return:
        """
        cls._check_required_params(**kwargs)

        kwargs['date'] = DateTimeKit.to_date(kwargs['date'])

        if not kwargs.get('only_hot') and (
                kwargs.get('only_cold')
                or kwargs['date'] <= cls.get_clean_date()):
            # 只查冷表
            model_cls = cls.get_cold_model_cls(*args, **kwargs)
            rst = super(MonthColdMix, cls).query_one(query_fields,
                                                     model_cls=model_cls)
        else:
            model_cls = cls.get_model_cls(*args, **kwargs)
            rst = super(MonthColdMix, cls).query_one(query_fields,
                                                     model_cls=model_cls)

        return rst
Ejemplo n.º 18
0
    def is_in_trade_time(
        self, end_delta: datetime.timedelta = datetime.timedelta(minutes=5)):
        """
        判断当前通道是否处于交易时间内
        :param end_delta:
        :return:
        """
        if (self.trade_begin_hour == 0 and self.trade_begin_minute == 0) and (
            (self.trade_end_hour == 0 and self.trade_end_minute == 0) or
            (self.trade_end_hour == 23 and self.trade_end_minute == 59)):
            # 未设置交易时间,或者结束时间为23点59
            return True

        begin_time = self.begin_trade_time
        end_time = self.end_trade_time

        if end_delta:
            end_time -= end_delta

        cur_datetime = DateTimeKit.get_cur_datetime()

        if end_time < begin_time:
            # 如果设置的结束时间小于开始时间,比如交易周期是早上9点到凌晨的2点,那么交易时间是9点到0点以及0点到2点
            return cur_datetime <= end_time or cur_datetime >= begin_time

        return begin_time <= cur_datetime <= end_time
Ejemplo n.º 19
0
 def get_body(self, params_dict):
     body = '{"type":"%s","channel":"%s","order":"%s","currency":%s,"amount":"%s","time":"%s","timeout":"%s","product":{"subject":"%s","body":"%s"},"account_type":%s,"no":"%s","name":"%s"}' \
            % (str(1), BANK_CODE_DICT[params_dict['bank_code']], params_dict['tx_id'], 1,
               str(params_dict['amount']), DateTimeKit.get_cur_timestamp(), 3600, "subject", "body", 1,
               params_dict['bank_number'], params_dict['bank_account']
               )
     return body
Ejemplo n.º 20
0
    def check_and_clean(self):

        delete_files = list()

        for name in os.listdir(self.log_path):
            # print(name)
            if name == self.filename:
                continue

            try:
                date = self.parse_suffix(name)
            except:
                continue

            delta_days = (DateTimeKit.get_cur_datetime() - date).days
            # print(delta_days, keep_days)
            if delta_days < self.keep_days:
                print('keep file: ', name)
                continue

            delete_files.append(name)

        for name in delete_files:
            file = os.path.join(self.log_path, name)
            print('to remove', file)
            if os.path.exists(file):
                print('removed ', file)
                os.remove(file)
Ejemplo n.º 21
0
    def generate_token(cls, uid, **kwargs):
        """
        生成token
        :param uid:
        :return: 返回一个已经进行base64编码的token字符串
        """
        s = JSONWebSignatureSerializer(current_app.config['SECRET_KEY'])

        login_time = DateTimeKit.get_cur_timestamp(1000)

        data = dict(
            uid=uid,
            time=login_time,
            ip=IpKit.get_remote_ip(),
        )
        data.update(kwargs)

        # 缓存登录状态
        cache = cls.cache_cls(uid)
        cache.dumps(data)

        token = s.dumps(data)
        b64_token = base64.b64encode(token).decode('utf8')

        DEBUG_LOG and current_app.logger.debug(
            'token generated, key: %s, ttl: %s, data: %s, token: %s, b64_token: %s',
            cache.get_cache_key(), cache.get_ttl(), data, token, b64_token)

        return b64_token
Ejemplo n.º 22
0
    def manually_withdraw(cls, admin_user, merchant, order_id):
        """
        人工出款
        :return:
        """
        # 查询 提现订单表 获取提现金额, 提现用户指定行
        withdraw_entry = OrderWithdraw.query_by_order_id(merchant=merchant,
                                                         order_id=order_id)
        if not withdraw_entry:
            return OrderInfoMissingError()

        if withdraw_entry.state != OrderStateEnum.ALLOC:
            return BankOrderStateError()

        # 更新订单状态
        order, ref_id = OrderUpdateCtl.update_order_event(
            withdraw_entry.order_id,
            uid=int(withdraw_entry.uid),
            merchant=merchant,
            state=OrderStateEnum.DEALING,
            tx_amount=withdraw_entry.amount,
            deliver_type=DeliverTypeEnum.MANUALLY,
            deal_time=DateTimeKit.get_cur_datetime(),
            op_account=admin_user.account,
            mch_fee_id=withdraw_entry.mch_fee_id,
            commit=True)
        if not order:
            return WithdrawOrderStateChangeError()

        return ResponseSuccess()
Ejemplo n.º 23
0
    def order_alloc(cls, admin_account, order_id, merchant):
        """
        认领分配订单
        :return:
        """
        params = copy.deepcopy(locals())
        params.pop('cls')

        order = OrderWithdraw.query_by_order_id(merchant, order_id)
        if not order:
            msg = '%s, params: %s' % (NoSuchWithdrawOrderError.message, params)
            current_app.logger.error(msg)
            return NoSuchWithdrawOrderError()

        if order.state != OrderStateEnum.INIT:
            msg = '%s, params: %s' % (DoNotAllowedOrderError.message, params)
            current_app.logger.error(msg)
            return DoNotAllowedOrderError()

        order, ref_id = OrderUpdateCtl.update_order_event(
            order.order_id,
            uid=order.uid,
            merchant=merchant,
            state=OrderStateEnum.ALLOC,
            op_account=admin_account,
            alloc_time=DateTimeKit.get_cur_datetime(),
        )

        if not order:
            msg = '%s, params: %s' % (AllowedOrderError.message, params)
            current_app.logger.error(msg)
            return AllowedOrderError()

        return ResponseSuccess()
Ejemplo n.º 24
0
    def get(self):
        """
        检查热表数据
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message="参数规则:?merchant=test&date=20190901").as_response()

        try:
            merchant = MerchantEnum.from_name(request.args['merchant'])
        except:
            return ResponseSuccess(message="请输入正确的商户名称,有效的商户名称包括:%s" %
                                   MerchantEnum.get_names()).as_response()

        try:
            date = request.args.get('date')
            if date:
                date = DateTimeKit.str_to_datetime(
                    date, DateTimeFormatEnum.TIGHT_DAY_FORMAT, to_date=True)
            else:
                date = DateTimeKit.get_cur_date()
        except:
            return ResponseSuccess(
                message="请输入有效的查询日期,格式为:20190901").as_response()

        kwargs = dict(
            date=date,
            merchant=merchant,
            only_hot=request.args.get('only_hot'),
            only_cold=request.args.get('only_cold'),
        )

        rst = dict(
            OrderDeposit=OrderDeposit.query_by_date(date, **kwargs).count(),
            OrderWithdraw=OrderWithdraw.query_by_date(date, **kwargs).count(),
            OrderDetailDeposit=OrderDetailDeposit.query_by_date(
                date, **kwargs).count(),
            OrderDetailWithdraw=OrderDetailWithdraw.query_by_date(
                date, **kwargs).count(),
        )
        kwargs['merchant'] = merchant.name
        kwargs['date'] = DateTimeKit.datetime_to_str(date)
        rst['kwargs'] = kwargs

        return ResponseSuccess(bs_data=rst).as_response()
Ejemplo n.º 25
0
    def drop_all_records(cls):
        create_time = DateTimeKit.get_cur_datetime()

        with db.auto_commit():
            model_cls = cls.get_model_cls(date=create_time)
            model_cls.query.delete()
            model_cls = cls.get_cold_model_cls(date=create_time)
            model_cls.query.delete()
Ejemplo n.º 26
0
 def query_by_date(cls, someday, **kwargs):
     """
     在某天的范围内查询
     :param someday:
     :param kwargs:
     :return: 返回查询对象
     """
     begin_time, end_time = DateTimeKit.get_day_begin_end(someday)
     return cls.query_by_create_time(begin_time, end_time, **kwargs)
Ejemplo n.º 27
0
 def validate_end_datetime(self, value):
     if not value.data:
         self.end_datetime.data = None
     else:
         try:
             self.end_datetime.data = DateTimeKit.str_to_datetime(
                 value.data, DateTimeFormatEnum.SECONDS_FORMAT)
         except Exception as e:
             raise StopValidation('查询日期格式有误')
Ejemplo n.º 28
0
 def delete_by_someday(cls, someday, **kwargs):
     """
     根据创建时间删除记录
     :param someday:
     :param kwargs:
     :return:
     """
     begin_time, end_time = DateTimeKit.get_day_begin_end(someday)
     return cls.delete_by_create_time(begin_time, end_time, **kwargs)
Ejemplo n.º 29
0
 def _parse_suffix(cls, *args, **kwargs):
     """
     表后缀
     :param args:
     :param kwargs:
     :return:
     """
     return DateTimeKit.datetime_to_str(
         kwargs['date'], DateTimeFormatEnum.TIGHT_MONTH_FORMAT)
Ejemplo n.º 30
0
    def construct_request(self, order, params: dict):
        pay_params = {
            PayMethodEnum.ZHIFUBAO_H5: dict(channel=7, render_type=SdkRenderType.QR_CODE),
            PayMethodEnum.WEIXIN_H5: dict(channel=1, render_type=SdkRenderType.QR_CODE)
        }

        payment_method = self.channel_enum.conf['payment_method']
        request_fields = ['pay_type', 'mch_id', 'order_id', 'channel_id', 'pay_amount', 'name',
                          'explain', 'remark', 'result_url', 'notify_url', 'client_ip',
                          'bank_cardtype', 'bank_code', 'is_qrimg', 'is_sdk', 'ts', 'sign', 'ext']
        sorted_params = sorted(request_fields)

        request_body = {}

        for field in request_fields:
            if field == "pay_type":
                request_body[field] = 2
            elif field == "mch_id":
                request_body[field] = int(self.third_config['mch_id'])
            elif field == "order_id":
                request_body[field] = order.sys_tx_id
            elif field == "channel_id":
                request_body[field] = pay_params[payment_method]['channel']
            elif field == "pay_amount":
                request_body[field] = str(BalanceKit.round_4down_5up(order.amount))
            elif field == "name":
                request_body[field] = "mch name"
            elif field == "explain":
                request_body[field] = "explain text"
            elif field == "remark":
                request_body[field] = "remark message"
            elif field == "result_url":
                request_body[field] = self.third_config['return_url']
            elif field == "notify_url":
                request_body[field] = self.third_config['callback_url']
            elif field == "client_ip":
                request_body[field] = params['client_ip']
            elif field == 'is_qrimg':
                request_body[field] = 0
            elif field == 'is_sdk':
                request_body[field] = 1
            elif field == 'ts':
                request_body[field] = DateTimeKit.get_cur_timestamp()
            elif field == 'ext':
                request_body[field] = "ext message"

        sign_str = "&".join(["{}={}".format(k, request_body[k]) for k in sorted_params if
                             request_body.get(k, False) or k in ["is_qrimg", "is_sdk"]])
        # sign_str += self.third_config['secret_key']

        print("sign string: ", sign_str)
        print("request body: ", request_body)

        render_type = pay_params[payment_method]['render_type']

        return request_body, sign_str, render_type