class UserMapping(db.Model): __tablename__ = 'user_mapping' id = db.Column(db.Integer, primary_key=True) user_domain_id = db.Column(db.Integer, db.ForeignKey('user_domain.id'), nullable=False) user_domain = db.relationship('UserDomain', backref=db.backref('user_maps', lazy='dynamic')) user_id = db.Column(db.VARCHAR(32), nullable=False) account_user_id = db.Column(db.Integer, nullable=False, unique=True) # 是否已开通 is_opened = db.Column(db.BOOLEAN, nullable=False, default=False) desc = db.Column(db.VARCHAR(64), default='') created_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) opened_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) # index # 目前<user_domain_id, user_id>唯一确定一个账号用户,之后可能对应多个 __table_args__ = (db.UniqueConstraint('user_domain_id', 'user_id', name='domain_user_id_uniq_idx'), ) def __repr__(self): return 'UserMapping<%r: %r, %r>' % (self.user_id, self.account_user_id, self.desc)
class ChannelPermission(db.Model): __tablename__ = 'channel_permission' id = db.Column(db.Integer, primary_key=True) channel_id = db.Column(db.Integer, db.ForeignKey('channel.id'), nullable=False) channel = db.relationship('Channel', backref=db.backref('perms', lazy='dynamic'), lazy='joined') api_entry_id = db.Column(db.Integer, db.ForeignKey('api_entry.id'), nullable=False) api_entry = db.relationship('ApiEntry', backref=db.backref('channel_perms', lazy='dynamic'), lazy='joined') created_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) __table_args__ = (db.UniqueConstraint('channel_id', 'api_entry_id', name='channel_api_entry_uniq_idx'), ) def __repr__(self): return 'ChannelPermission<%r->%r>' % (self.channel.name, self.api_entry.path)
class ApiEntry(db.Model): __tablename__ = 'api_entry' id = db.Column(db.Integer, primary_key=True) super_id = db.Column(db.Integer, db.ForeignKey('api_entry.id'), nullable=True, default=None) super = db.relationship('ApiEntry', remote_side=id, backref=db.backref('subs', lazy='dynamic'), lazy='joined') name = db.Column(db.VARCHAR(64), nullable=False, index=True) value = db.Column(db.VARCHAR(256), nullable=True) created_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) updated_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = (db.UniqueConstraint('super_id', 'name', name='super_id_name_uniq_idx'), ) @staticmethod def load_trie(): from api_x.utils import ds trie = ds.Trie() api_entries = ApiEntry.query.all() for api_entry in api_entries: if api_entry.value is not None: trie.put(api_entry.path, api_entry) return api_entries, trie @property def path(self): s, path = self, tuple() while s is not None: path = (s.name, ) + path s = s.super return path @property def id_path(self): s, path = self, tuple() while s is not None: path = (s.id, ) + path s = s.super return path def __repr__(self): return 'ApiEntry<%r>' % (self.path, )
class Bankcard(db.Model): __tablename__ = 'bankcard' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, nullable=False) # 0-对私, 1-对公 flag = db.Column(db.SmallInteger, nullable=False) card_no = db.Column(db.VARCHAR(21), nullable=False) card_type = db.Column(db.Enum('DEBIT', 'CREDIT'), nullable=False) acct_name = db.Column(db.VARCHAR(32), nullable=False) bank_code = db.Column(db.CHAR(9), nullable=False) province_code = db.Column(db.VARCHAR(12), nullable=False) city_code = db.Column(db.VARCHAR(12), nullable=False) bank_name = db.Column(db.VARCHAR(32), nullable=False) brabank_name = db.Column(db.VARCHAR(50), nullable=False) prcptcd = db.Column(db.CHAR(12), default='') is_bounded = db.Column(db.Boolean, nullable=False, default=True) created_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) updated_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) # index __table_args__ = (db.UniqueConstraint('user_id', 'card_no', name='user_card_uniq_idx'), ) def to_dict(self): return { 'id': self.id, 'flag': self.flag, 'card_no': self.card_no, 'card_type': self.card_type, 'acct_name': self.acct_name, 'bank_code': self.bank_code, 'province_code': self.province_code, 'city_code': self.city_code, 'bank_name': self.bank_name, 'brabank_name': self.brabank_name, 'prcptcd': self.prcptcd, 'created_on': self.created_on } def __repr__(self): return 'Bankcard<%r, %r>' % (self.card_no, self.bank_name)
class EvasAlipayBatchRefundRecord(db.Model): __tablename__ = 'evas_alipay_batch_refund_record' id = db.Column(db.BigInteger, primary_key=True) batch_no = db.Column(db.VARCHAR(64), nullable=False) trade_no = db.Column(db.VARCHAR(64), nullable=False) refund_tx_sn = db.Column(db.VARCHAR(64), nullable=False, unique=True) created_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) updated_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = (db.UniqueConstraint('batch_no', 'trade_no', name='batch_no_trade_no_uniq_idx'), ) def __repr__(self): return '<AlipayBatchRefund %r->%r:%r>' % (self.batch_no, self.tx_sn, self.refund_tx_sn)
class PaymentRecord(db.Model): __tablename__ = 'payment_record' id = db.Column(db.BigInteger, primary_key=True) tx_id = db.Column(db.BigInteger, db.ForeignKey('transaction.id'), nullable=False, unique=True) tx = db.relationship('Transaction', backref=db.backref('payment_record', lazy='dynamic'), lazy='joined') sn = db.Column(db.CHAR(32), nullable=False) type = db.Column(db.Enum(PaymentType.DIRECT, PaymentType.GUARANTEE), nullable=False) payer_id = db.Column(db.Integer, nullable=False) payee_id = db.Column(db.Integer, nullable=False) channel_id = db.Column(db.Integer, nullable=False) order_id = db.Column(db.VARCHAR(64), nullable=False) origin = db.Column(db.VARCHAR(32), default=None) product_name = db.Column(db.VARCHAR(150), nullable=False) product_category = db.Column(db.VARCHAR(50), nullable=False) product_desc = db.Column(db.VARCHAR(350), nullable=False) amount = db.Column(db.Numeric(16, 2), nullable=False) real_amount = db.Column(db.Numeric(16, 2), nullable=False, default=0) paid_amount = db.Column(db.Numeric(16, 2), nullable=False, default=0) refunded_amount = db.Column(db.Numeric(16, 2), nullable=False, default=0) client_callback_url = db.Column(db.VARCHAR(128)) client_notify_url = db.Column(db.VARCHAR(128)) created_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) tried_times = db.Column(db.Integer, nullable=False, default=1) updated_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) # index __table_args__ = (db.UniqueConstraint( 'channel_id', 'order_id', 'origin', name='channel_order_id_origin_uniq_idx'), ) def is_finished(self): return self.real_amount == self.paid_amount - self.refunded_amount @transactional def add_refund(self, refund_record, event_id): from api_x.constant import PaymentTxState from api_x.zyt.biz.transaction import transit_transaction_state self.refunded_amount += refund_record.amount # 全部金额都退款,则状态为已退款 is_refunded = self.paid_amount == self.refunded_amount if self.tx.state == PaymentTxState.REFUNDING: if is_refunded: transit_transaction_state(self.tx_id, PaymentTxState.REFUNDING, PaymentTxState.REFUNDED, event_id) else: transit_transaction_state(self.tx_id, PaymentTxState.REFUNDING, refund_record.payment_state, event_id) db.session.add(self) super_tx = self.tx.super if super_tx and super_tx.type == TransactionType.PAYMENT: super_payment = super_tx.record super_payment.add_refund(refund_record, event_id) @transactional def add_paid(self, amount): self.paid_amount += amount db.session.add(self) super_tx = self.tx.super if super_tx and super_tx.type == TransactionType.PAYMENT: super_payment = super_tx.record super_payment.add_paid(amount) def __repr__(self): return '<Payment %r, %r->%r$%r:%r:%r/%r>' % ( self.id, self.payer_id, self.payee_id, self.amount, self.real_amount, self.paid_amount, self.refunded_amount)