Esempio n. 1
0
    def get(self):
        """
        商户配置查询
        :return:
        """
        if not request.args:
            return ResponseSuccess(message="参数规则:?merchant=test").as_response()

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

        merchant_info = MerchantInfo.query_merchant(merchant)
        if not merchant_info:
            return ResponseSuccess(message="未创建商户").as_response()

        bs_data = dict(
            balance=dict(
                balance_total=str(merchant_info.balance_total),
                balance_available=str(merchant_info.balance_available),
                balance_income=str(merchant_info.balance_income),
                balance_frozen=str(merchant_info.balance_frozen),
            ),
            merchant=merchant.name,
            domains=MerchantDomainConfig.get_domains(merchant),
            # db=DBEnum(merchant.name).get_db_name(),
        )

        deposit_fees = MerchantFeeConfig.query_active_configs(
            query_fields=dict(
                merchant=merchant,
                payment_way=PayTypeEnum.DEPOSIT,
            ))
        deposit_fees = MerchantFeeConfig.filter_latest_items(deposit_fees)
        if not deposit_fees:
            return MerchantConfigDepositError(bs_data=bs_data).as_response()
        bs_data['deposit_fees'] = [x.short_description for x in deposit_fees]

        withdraw_fees = MerchantFeeConfig.query_latest_one(query_fields=dict(
            merchant=merchant,
            payment_way=PayTypeEnum.WITHDRAW,
        ))
        if not withdraw_fees:
            return MerchantConfigWithdrawError(bs_data=bs_data).as_response()
        bs_data['withdraw_fees'] = withdraw_fees.short_description

        channels = ChannelListHelper.get_available_channels(
            merchant, PayTypeEnum.DEPOSIT)
        bs_data['deposit_channels'] = [x.short_description for x in channels]

        channels = ChannelListHelper.get_available_channels(
            merchant, PayTypeEnum.WITHDRAW)
        bs_data['withdraw_channels'] = [x.short_description for x in channels]

        return ResponseSuccess(bs_data=bs_data).as_response()
Esempio n. 2
0
    def get(self):
        """
        查询可用的通道
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message="参数规则:?merchant=test&interface=&amount=&uid="
            ).as_response()

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

        try:
            interface = request.args.get('interface')
            if interface:
                interface = InterfaceTypeEnum.from_name(interface)
        except:
            return ResponseSuccess(
                message="请输入正确的 interface,有效的 interface 包括:%s" %
                InterfaceTypeEnum.get_names()).as_response()

        try:
            amount = request.args.get('amount') or 0
            if amount:
                amount = Decimal(amount)
        except:
            return ResponseSuccess(message="请输入正确的 amount")

        try:
            uid = request.args.get('uid')
            if uid:
                uid = int(uid)
        except:
            return ResponseSuccess(message="请输入正确的 uid")

        routers = ChannelListHelper.get_channel_payment_type_router(
            interface=interface,
            amount=amount,
            merchant=merchant,
            uid=uid,
        )
        channels = ChannelListHelper.get_available_channels(
            merchant, PayTypeEnum.DEPOSIT)
        payment_type_list = ChannelListHelper.choice_one_channel_for_payment_type(
            channels, routers, merchant, amount)

        for item in payment_type_list:
            item['limit_min'] = str(item['limit_min'])
            item['limit_max'] = str(item['limit_max'])

        return ResponseSuccess(bs_data=payment_type_list).as_response()
Esempio n. 3
0
    def get(self):
        """
        给用户绑定信息
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message=
                "参数规则:?merchant=test&account=861891111&perm=DEPOSIT|BINDCARD"
            ).as_response()

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

        try:
            account = request.args['account']
            account = '+' + account.strip('+').strip()
            if not PhoneNumberParser.is_valid_number(account):
                raise
        except:
            return ResponseSuccess(
                message="请输入正确的用户手机号码,必须有完整区号,不填+号,如:8613812349999"
            ).as_response()

        try:
            perms = request.args['perm'].split('|')
            perms = [UserPermissionEnum.from_name(perm) for perm in perms]
        except:
            return ResponseSuccess(
                message="标签权限,有效的权限包括: %s" %
                UserPermissionEnum.get_name_list()).as_response()

        user = User.query_user(merchant, account=account)
        if not user:
            return ResponseSuccess(message="手机号码未注册").as_response()

        User.update_user_permission(merchant, perms, account=account)
        user = User.query_user(merchant, account=account)

        bs_data = dict(
            account=account,
            uid=user.uid,
            perms=user.permission_names,
        )
        return ResponseSuccess(bs_data=bs_data).as_response()
Esempio n. 4
0
    def get(self):
        """
        给用户绑定信息
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message="参数规则:?merchant=test&account=861891111&flag=VIP"
            ).as_response()

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

        try:
            account = request.args['account']
            account = '+' + account.strip('+').strip()
            if not PhoneNumberParser.is_valid_number(account):
                raise
        except:
            return ResponseSuccess(
                message="请输入正确的用户手机号码,必须有完整区号,不填+号,如:8613812349999"
            ).as_response()

        try:
            flag = AccountFlagEnum.from_name(request.args['flag'])
        except:
            return ResponseSuccess(
                message="标签错误,有效的标签包括: %s" %
                AccountFlagEnum.get_name_list()).as_response()

        user = User.query_user(merchant, account=account)
        if not user:
            return ResponseSuccess(message="手机号码未注册").as_response()

        User.update_user_flag(merchant, flag, account=account)
        user = User.query_user(merchant, account=account)

        bs_data = dict(
            account=account,
            uid=user.uid,
            flag=user.flag.desc,
            is_auth=user.is_official_auth,
            cache_flag=UserFlagCache(user.uid).get_flag().name,
        )
        return ResponseSuccess(bs_data=bs_data).as_response()
Esempio n. 5
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()
Esempio n. 6
0
    def get(self):
        """
        查询用户余额
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message="参数规则:?account=8613812349999&merchant=test"
            ).as_response()

        try:
            account = request.args.get('account')
            if account:
                account = '+' + account.strip('+').strip()
                if not PhoneNumberParser.is_valid_number(account):
                    raise
            else:
                raise
        except:
            return ResponseSuccess(
                message="请输入正确的用户手机号码,必须有完整区号,不填+号,如:8613812349999"
            ).as_response()

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

        user = User.query_user(merchant, account=account)
        if not user:
            return ResponseSuccess(message="手机号码未注册, account: %s" %
                                   account).as_response()

        user_balance = UserBalance.query_balance(user.uid, merchant).first()

        return ResponseSuccess(bs_data=dict(
            account=account,
            uid=user.uid,
            balance=str(user_balance.real_balance),
        )).as_response()
Esempio n. 7
0
    def test_merchant_fee_config_model(self):
        # 添加测试
        count = 0
        latest_count = 0
        for merchant in MerchantEnum:
            for payment_way in PayTypeEnum:
                if payment_way == PayTypeEnum.DEPOSIT:
                    for payment_method in PayMethodEnum:
                        for fee_type in PaymentFeeTypeEnum:
                            params = [
                                dict(
                                    merchant=merchant,
                                    payment_way=payment_way,
                                    payment_method=payment_method,
                                    fee_type=fee_type,
                                    value=Decimal("1.22"),
                                ),
                            ]
                            self.add_one_config(merchant, params)
                            count += 1
                        latest_count += 1
                else:
                    for fee_type in PaymentFeeTypeEnum:
                        params = [
                            dict(
                                merchant=merchant,
                                payment_way=payment_way,
                                fee_type=fee_type,
                                value=Decimal("3.22"),
                            ),
                        ]
                        self.add_one_config(merchant, params)
                        count += 1
                    latest_count += 1

        all_configs = MerchantFeeConfig.query_all()
        add_num = len(list(all_configs))
        self.assertEqual(count, add_num)

        latest_configs = MerchantFeeConfig.filter_latest_items(all_configs)
        x_latest_count = len(list(latest_configs))
        self.assertEqual(len(MerchantEnum.get_names()), x_latest_count)

        # 修改测试
        count = 0
        for merchant in MerchantEnum:
            for payment_way in PayTypeEnum:
                if payment_way == PayTypeEnum.DEPOSIT:
                    for payment_method in PayMethodEnum:
                        for fee_type in PaymentFeeTypeEnum:
                            params = [
                                dict(
                                    merchant=merchant,
                                    payment_way=payment_way,
                                    payment_method=payment_method,
                                    fee_type=fee_type,
                                    value=Decimal("1.33"),
                                ),
                            ]
                            self.add_one_config(merchant, params)
                            count += 1
                else:
                    for fee_type in PaymentFeeTypeEnum:
                        params = [
                            dict(
                                merchant=merchant,
                                payment_way=payment_way,
                                fee_type=fee_type,
                                value=Decimal("2.33"),
                            ),
                        ]
                        self.add_one_config(merchant, params)
                        count += 1

        add_num += count

        # 更新不会增加条目
        all_configs = MerchantFeeConfig.query_all()
        num = len(list(all_configs))
        self.assertEqual(add_num, num)

        latest_configs = MerchantFeeConfig.filter_latest_items(all_configs)
        x_latest_count = len(list(latest_configs))
        self.assertEqual(len(MerchantEnum.get_names()), x_latest_count)

        # 批量修改测试
        count = 0
        valid_count = 0
        for merchant in MerchantEnum:
            params = []
            for payment_way in PayTypeEnum:
                if payment_way == PayTypeEnum.DEPOSIT:
                    for payment_method in PayMethodEnum:
                        params.append(dict(
                            merchant=merchant,
                            payment_way=payment_way,
                            payment_method=payment_method,
                            fee_type=PaymentFeeTypeEnum.PERCENT_PER_ORDER,
                            value=Decimal("1.22"),
                        ))
                        count += 1
                else:
                    params.append(dict(
                        merchant=merchant,
                        payment_way=payment_way,
                        fee_type=PaymentFeeTypeEnum.PERCENT_PER_ORDER,
                        value=Decimal("3.22"),
                    ))
                    count += 1

            valid_count += len(params)
            self.add_one_config(merchant, params)

        add_num += count

        all_configs = MerchantFeeConfig.query_all()
        num = len(list(all_configs))
        self.assertEqual(add_num, num)

        latest_configs = MerchantFeeConfig.filter_latest_items(all_configs)
        x_latest_count = len(list(latest_configs))
        self.assertEqual(valid_count, x_latest_count)

        MerchantFeeConfig.delete_all()
        num = len(list(MerchantFeeConfig.query_all()))
        self.assertEqual(0, num)
Esempio n. 8
0
    "fee_type": fields.Nested(DescValuePair),
    "limit_per_min": fields.String(required=True, description='单笔交易下限'),
    "limit_per_max": fields.String(required=True, description='单笔交易上限'),
    "limit_day_max": fields.String(required=True, description='日交易限额'),
    "settlement_type": fields.Nested(NameValuePair),
    "trade_start_time": fields.String(required=True, description='交易开始时间'),
    "trade_end_time": fields.String(required=True, description='交易结束时间'),
    "main_time": fields.Nested(maintain_datetime),
    "state": fields.Nested(DescValuePair, description="可操作类型列表"),
    "reason": fields.String(required=True, description='不可用原因'),
    "priority": fields.String(required=True, description='优先级'),
    "merchants": fields.List(
        fields.String,
        required=True,
        description='适用的商户列表',
        example=MerchantEnum.get_names(),
    ),
})

ChannelList = api.model('ChannelList', {
    'counts': fields.String(
        required=True,
        description='渠道总个数',
        example="10"
    ),
    'channels': fields.List(fields.Nested(ChannelItem)),
})


class ChannelListResult(ResponseSuccess):
    data_model = ChannelList
Esempio n. 9
0
    def get(self):
        """
        查询用户余额变更流水
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message=
                "参数规则:?merchant=test&account=8618912341234&date=20190901&export=1"
            ).as_response()

        try:
            account = request.args.get('account')
            if account:
                account = '+' + account.strip('+').strip()
                if not PhoneNumberParser.is_valid_number(account):
                    raise
        except:
            return ResponseSuccess(
                message="请输入正确的用户手机号码,必须有完整区号,不填+号,如:8613812349999"
            ).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()

        rst = dict(
            data=list(),
            sum_value=0,
        )

        events = UserBalanceEvent.query_by_date(date,
                                                merchant=merchant,
                                                date=date)
        if account:
            user = User.query_user(merchant, account=account)
            if not user:
                return ResponseSuccess(message="用户不存在,请检查参数。商户:%s,手机号码:%s" %
                                       (merchant.name, account))

            user_balance = UserBalance.query_balance(user.uid,
                                                     merchant).first()
            rst.update(user=dict(
                account=user.account,
                uid=user.uid,
                user_balance=str(user_balance.real_balance),
            ))
            events = events.filter_by(uid=user.uid)

        rst['sql'] = str(events)
        for event in events:
            rst['sum_value'] += event.value_real
            rst['data'].append(
                dict(
                    create_time=event.create_time,
                    uid=event.uid,
                    ref_id=event.ref_id,
                    order_type=event.order_type.desc,
                    source=event.source.desc,
                    bl_type=event.bl_type.desc,
                    value=str(event.value_real),
                    ad_type=event.ad_type.desc,
                    tx_id=event.tx_id,  # 大整数,转为字符串
                    comment=event.comment,
                    extra=event.raw_extra,
                ))

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

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

        rst['sum_value'] = str(rst['sum_value'])

        return ResponseSuccess(bs_data=rst).as_response()
Esempio n. 10
0
    def get(self):
        """
        查询商户余额变更流水
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message="参数规则:?merchant=test&date=20190901&export=1"
            ).as_response()

        try:
            merchant = MerchantEnum.from_name(request.args['merchant'])
            merchant_info = MerchantInfo.query_merchant(merchant)
            if not merchant_info:
                raise
        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()

        balance = dict(
            balance_total=str(merchant_info.balance_total),
            balance_available=str(merchant_info.balance_available),
            balance_income=str(merchant_info.balance_income),
            balance_frozen=str(merchant_info.balance_frozen),
        )

        events = MerchantBalanceEvent.query_by_date(date,
                                                    merchant=merchant,
                                                    date=date)

        rst = dict(
            data=list(),
            sum_value=0,
            balance=balance,
        )

        rst['sql'] = str(events)

        for event in events:
            rst['sum_value'] += event.value_real
            rst['data'].append(
                dict(
                    create_time=event.create_time,
                    ref_id=event.ref_id,
                    order_type=event.order_type.desc,
                    source=event.source.desc,
                    bl_type=event.bl_type.desc,
                    value=str(event.value_real),
                    ad_type=event.ad_type.desc,
                    tx_id=event.tx_id,
                    comment=event.comment,
                ))

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

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

        rst['sum_value'] = str(rst['sum_value'])

        return ResponseSuccess(bs_data=rst).as_response()
Esempio n. 11
0
    def get(self):
        """
        给用户绑定信息
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message="参数规则:?merchant=test&account=861891111&name=大王&unbind="
            ).as_response()

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

        try:
            account = request.args['account']
            account = '+' + account.strip('+').strip()
            if not PhoneNumberParser.is_valid_number(account):
                raise
        except:
            return ResponseSuccess(
                message="请输入正确的用户手机号码,必须有完整区号,不填+号,如:8613812349999"
            ).as_response()

        try:
            name = request.args['name']
        except:
            return ResponseSuccess(message="绑定名称必填").as_response()

        user = User.query_user(merchant, account=account)
        if not user:
            return ResponseSuccess(message="手机号码未注册").as_response()

        bind_info = UserBindInfo.query_bind_by_uid(user.uid)

        if request.args.get('unbind'):
            if not bind_info:
                return ResponseSuccess(message="未绑定任何别名,无需解绑").as_response()

            if UserBindInfo.unbind_account(user.uid):
                return ResponseSuccess(message="解绑成功").as_response()
            else:
                return ResponseSuccess(message="解绑失败").as_response()
        else:
            if not bind_info:
                if UserBindInfo.bind_account(user.uid,
                                             merchant,
                                             account=user.account,
                                             name=name):
                    msg = "绑定成功"
                else:
                    msg = "绑定失败"
                    return ResponseSuccess(message=msg).as_response()
            else:
                msg = "无需重复绑定,已经绑定名称:%s" % bind_info.name

            bind_info = UserBindInfo.query_bind_by_uid(user.uid)
            bs_data = dict(
                name=bind_info.name,
                account=bind_info.account,
                uid=user.uid,
            )
            return ResponseSuccess(bs_data=bs_data, message=msg).as_response()