11.5 发送鱼漂

1.业务逻辑编写

当用户在像其他用户发起一个赠书请求的时候,这实际上就是一次交易的发起,我们将这个交易起名为鱼漂(Drift),具体业务逻辑如下

image.png

2.模型设计

models/drift.py

class Drift(Base):
    """
        一次具体的交易信息
    """
    __tablename__ = 'drift'

    id = Column(Integer, primary_key=True)

    # 邮寄信息
    recipient_name = Column(String(20), nullable=False)
    address = Column(String(100), nullable=False)
    message = Column(String(200))
    mobile = Column(String(20), nullable=False)

    # 书籍信息
    isbn = Column(String(13))
    book_title = Column(String(50))
    book_author = Column(String(30))
    book_img = Column(String(50))

    # 请求者信息
    requester_id = Column(Integer)
    requester_nickname = Column(String(20))

    # 赠送者信息
    gifter_id = Column(Integer)
    gift_id = Column(Integer)
    gifter_nickname = Column(String(20))

    # 状态
    _pending = Column('pending', SmallInteger, default=1)

状态信息应该使用枚举类

class PendingStatus(Enum):
    Waiting = 1
    Success = 2
    Reject = 3
    Redraw = 4

模型冗余而不是模型关联?

1.Drift旨在记录历史状态,而模型关联记录的是实时关联的。所以应该在Drift中直接平铺所有信息

2.模型关联是使得每次查询的时候多次关联,降低查询速度

3.鱼漂条件检测

1.自己不能够向自己索要数据 models/gift.py

    def is_yourself_gift(self, uid):
        return uid == self.uid

2.鱼豆数量必须大于等于1 3.每索取两本书,必须赠送一本书 models/user.py

    def can_send_drifts(self):
        if self.beans < 1:
            return False
        success_gift_count = Gift.query.filter_by(
            uid=self.id, launched=True).count()
        success_receive_count = Drift.query.filter_by(
            uid=self.id, pending=PendingStatus.Success).count()

        return floor(success_receive_count / 2) <= success_gift_count

4.完成鱼漂业务逻辑

试图函数

web/drift.py

@web.route('/drift/<int:gid>', methods=['GET', 'POST'])
@login_required
def send_drift(gid):
    current_gift = Gift.query.get_or_404(gid)
    if current_gift.is_yourself_gift(current_user.id):
        flash('这本书是自己的(*^▽^*),不能向自己索要哦')
        return redirect(url_for('web.book_detail', isbn=current_gift.isbn))

    can = current_user.can_send_drifts()
    if not can:
        return render_template('not_enough_beans.html', beans=current_user.beans)

    form = DriftForm(request.form)
    if request.method == 'POST' and form.validate():
        save_drift(form, current_gift)
        send_mail(current_gift.user.email, '有人想要一本书', 'email/get_gift.html',
                  wisher=current_user,
                  gift=current_gift)
        # 成功后跳转到鱼漂历史记录界面
        return redirect(url_for('web.pending'))

    # summary用户的简介频繁使用,且更像是一种用户的属性,所以作为用户的一个属性
    gifter = current_gift.user.summary
    return render_template('drift.html', gifter=gifter, user_beans=current_user.beans, form=form)

models/user.py

    @property
    def summary(self):
        return dict(
            nikename=self.nickname,
            beans=self.beans,
            email=self.email,
            send_receive=str(self.send_counter) + '/' + str(self.receive_counter)
        )

save_gift.py

def save_drift(drift_form, current_gift):
    if current_user.beans < 1:
        # TODO 自定义异常
        raise Exception()

    with db.auto_commit():
        drift = Drift()
        drift_form.populate_obj(drift)

        drift.gift_id = current_gift.id
        drift.requester_id = current_user.id
        drift.requester_nickname = current_user.nickname
        drift.gifter_nickname = current_gift.user.nickname
        drift.gifter_id = current_gift.user.id

        book = BookViewModel(current_gift.book)
        drift.book_title = book.title
        drift.book_author = book.author
        drift.book_img = book.image
        drift.isbn = book.isbn

        db.session.add(drift)

        current_user.beans -= 1

Last updated

Was this helpful?