class Payment(db.Model): __tablename__ = 'payment' # 充值 TYPE_RECHARGE = 0 # 购买 TYPE_BUY = 1 STATUS_PENDING = 0 STATUS_PAID = 1 id = db.Column(db.Integer, primary_key=True) # 那个用户支付的 user_id = db.Column(db.Integer, nullable=False) # 支付的状态 status = db.Column(db.Integer, default=STATUS_PENDING) # 支付类型 是购买还是充值 payment_type = db.Column(db.Integer) # 支付流水账号 payment_no = db.Column(db.String(32)) # 此次支付行动的额度 amount = db.Column(db.Integer) created_at = db.Column(db.DateTime, default=datetime.now) paid_at = db.Column(db.DateTime, default=None) # 备注信息 _remark = db.Column('remark', db.Text, default='{}') @classmethod def create(cls, user_id, amount, payment_type): payment_no = gen_payment_no(user_id) payment = cls(user_id=user_id, payment_no=payment_no, amount=amount, payment_type=payment_type) db.session.add(payment) db.session.commit() return payment @classmethod def get_by_payment_no(cls, payment_no): return cls.query.filter_by(payment_no=payment_no).first() @property def remark(self): return json.loads(self._remark or '{}') @remark.setter def remark(self, value): self._remark = json.dumps(value)
class PocketHistory(db.Model): __tablename__ = 'pocket_history' id = db.Column(db.Integer, primary_key=True) # 用户信息 user_id = db.Column(db.Integer, nullable=False) # 产品信息 这里不应该是绑定关系的 product_id = db.Column(db.Integer, nullable=True) # 消费或者充值额度 total_fee = db.Column(db.Integer, nullable=False) # 总钱数目 balance = db.Column(db.Integer, nullable=False) # 描述 description = db.Column(db.String(512)) created_at = db.Column(db.DateTime, default=datetime.utcnow) @classmethod def get_multi_by_user_id(cls, user_id): return (cls.query.filter_by(user_id=user_id).order_by( cls.id.desc()).limit(5).all()) def as_resp(self): return { 'total_fee': self.total_fee, 'description': self.description, 'created_at': self.created_at.strftime('%Y-%m-%d'), }
class Mode(db.Model): __tablename__ = 'mode' # 默认每天扣费情况 DEFAULT_FEE = 200 id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(32), unique=True) description = db.Column(db.String(1024)) price = db.Column(db.Integer) def save(self): db.session.add(self) db.session.commit() @classmethod def get(cls, id_): return cls.query.get(id_) @classmethod def get_default_id(cls): modes = cls.query.all() if modes and len(modes) > 0: return modes[0].id @classmethod def get_mode_fee(cls, mode_id): mode = cls.query.get(mode_id) if mode is None: return cls.DEFAULT_FEE return mode.price @classmethod def get_all(cls): return cls.query.all() def as_resp(self): return { 'id': self.id, 'name': self.name, 'description': self.description, 'price': self.price }
class ExternalUser(db.Model): __tablename__ = 'external_user' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, nullable=False) external_uid = db.Column(db.String(256), nullable=False) provider = db.Column(db.String(32), nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
class Product(db.Model): __tablename__ = 'product' # 产品的ID信息 id = db.Column(db.Integer, primary_key=True) # 产品名称 name = db.Column(db.String(128), unique=True, nullable=False) # 产品价格 price = db.Column(db.Integer) # 产品描述 description = db.Column(db.String(1024), nullable=True) avatar_url = db.Column(db.String(1024), nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) deleted_at = db.Column(db.DateTime, default=None) def save(self): db.session.add(self) db.session.commit() @classmethod def get(cls, id_): return cls.query.get(id_) @classmethod def get_all(cls): return cls.query.all() def as_resp(self): return { 'id': self.id, 'name': self.name, 'description': self.description, 'avatar_url': self.avatar_url, 'price': self.price, }
class OrderItem(db.Model): __tablename__ = 'order_item' id = db.Column(db.Integer, primary_key=True) # 箱子的编号!!! 根据时间和用户信息生成的 item_id = db.Column(db.String(128), nullable=True) # 购买的用户 user_id = db.Column(db.Integer, nullable=False) # 属于哪一种产品 product_id = db.Column(db.Integer, nullable=False) # 属于哪一个订单的 order_id = db.Column(db.Integer, nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) @classmethod def create(cls, user_id, product_id, order_id): obj = cls(user_id=user_id, product_id=product_id, order_id=order_id) db.session.add(obj) db.session.commit() return obj @classmethod def get_multi_by_order_id(cls, order_id): return cls.query.filter_by(order_id=order_id).all() def as_resp(self): product = Product.get(self.product_id) return { 'id': self.id, 'item_id': self.item_id, 'product': product.as_resp(), }
class Intentory(db.Model): __tablename__ = 'intentory' id = db.Column(db.Integer, primary_key=True) product_id = db.Column(db.Integer, nullable=False) count = db.Column(db.Integer, nullable=False)
class Pocket(db.Model): __tablename__ = 'pocket' id = db.Column(db.Integer, primary_key=True) # 用户信息 user_id = db.Column(db.Integer, nullable=False) # 钱包总额 balance = db.Column(db.Integer) @classmethod def create(cls, user_id, balance=0): p = cls(user_id=user_id, balance=balance) db.session.add(p) db.session.commit() return p @classmethod def get_or_create_by_user_id(cls, user_id): p = cls.query.filter_by(user_id=user_id).first() if p is not None: return p return cls.create(user_id) # 充值 def add(self, amount, product=None, description=None): self.balance += amount db.session.add(self) if product is None: product_id = None else: product_id = product.id # 增加充值记录 ph = PocketHistory( user_id=self.user_id, product_id=product_id, total_fee=amount, balance=self.balance, description=description, ) db.session.add(ph) db.session.commit() # 消费 def cut_down(self, amount, product=None, description=None): self.balance -= amount db.session.add(self) if product is None: product_id = None else: product_id = product.id # 增加消费记录 ph = PocketHistory( user_id=self.user_id, product_id=product_id, total_fee=-amount, balance=self.balance, description=description, ) db.session.add(ph) db.session.commit() def as_resp(self): history = PocketHistory.get_multi_by_user_id(self.user_id) return { 'user_id': self.id, 'balance': self.balance, 'history': [each.as_resp() for each in history] }
class Address(db.Model): __tablename__ = 'address' id = db.Column(db.Integer, primary_key=True) # 对应的User 表 ID 一个用户会有多个address user_id = db.Column(db.Integer, nullable=False) # 省份 province = db.Column(db.String(16)) # 市 city = db.Column(db.String(64)) # 区域 area = db.Column(db.String(32)) # 详细地址 location = db.Column(db.String(128)) # 联系人名称 contact_name = db.Column(db.String(32)) # 联系人电话 contact_phone = db.Column(db.String(32)) created_at = db.Column(db.DateTime, default=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # todo 逻辑删除标识??? deleted_at = db.Column(db.DateTime, default=None) # 根据用户ID 获取多个地址信息 @classmethod def get_multi_by_uid(cls, user_id): return cls.query.filter_by(user_id=user_id).all() # 地址ID 信息 @classmethod def get(cls, address_id): return cls.query.get(address_id) # 创建地址对象 @classmethod def create(cls, user_id, province, city, area, location, contact_name, contact_phone): address = Address(user_id=user_id, province=province, city=city, area=area, location=location, contact_name=contact_name, contact_phone=contact_phone) db.session.add(address) db.session.commit() return address def delete(self): db.session.delete(self) db.session.commit() def save(self): db.session.add(self) db.session.commit() def as_resp(self): return { 'id': self.id, 'user_id': self.user_id, 'province': self.province, 'city': self.city, 'area': self.area, 'location': self.location, 'contact_name': self.contact_name, 'contact_phone': self.contact_phone, }
class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) # 用户名 username = db.Column(db.String(64), nullable=True) # 密码 password = db.Column(db.String(128), nullable=False) # 邮箱 email = db.Column(db.String(256), nullable=True) # 手机 mobile = db.Column(db.String(16), nullable=False) # 昵称 nickname = db.Column(db.String(32), nullable=False) # todo 尚未完全搞清 openid = db.Column(db.String(512), nullable=True) # todo 尚未完全搞清 avatar_url = db.Column(db.String(512), nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # todo 逻辑删除标识?? deleted_at = db.Column(db.DateTime, default=None) @classmethod def get_by_user_id(cls, user_id): return cls.query.get(user_id) @classmethod def get_by_mobile(cls, mobile): return cls.query.filter_by(mobile=mobile).first() @classmethod def get_by_openid(cls, openid): return cls.query.filter_by(openid=openid).first() @classmethod def create(cls, mobile, openid): user = User( password='', mobile=mobile, # todo 昵称需要通过微信端获取 参考 http://www.cnblogs.com/txw1958/p/weixin76-user-info.html nickname='', openid=openid, avatar_url='/images/avatar.png', ) db.session.add(user) db.session.commit() return user def as_resp(self): return { 'id': self.id, 'username': self.username, 'email': self.email, 'mobile': self.mobile, 'nickname': self.nickname, 'avatar_url': self.avatar_url, }
class Collecation(db.Model): __tablename__ = 'collecation' # 最大剩余天数 DEFAULT_MAX_REMAIN_DAYS = 2147483647 # 未被使用 STATUS_UNUSE = 0 # todo 不知何意 # STATUS_REQUESTED = 1 # 正在被使用 正在进行中? STATUS_USING = 2 # # todo 既然有被使用中 为何还需要被使用过字段? 已经被使用? # STATUS_USED = 3 id = db.Column(db.Integer, primary_key=True) # 存储的用户信息 user_id = db.Column(db.Integer, nullable=False) # 存储计费方式 mode_id = db.Column(db.Integer, nullable=True) # 箱子的编码信息,通过时间和用户信息生成 item_id = db.Column(db.String(32), nullable=False) # 当前箱子的使用状态 status = db.Column(db.Integer, nullable=False, default=STATUS_UNUSE) # 存储天数 已经存了多少天了 days = db.Column(db.Integer, nullable=False, default=0) # 剩余天数 通过余额计算出来的 已入库后才开始进行剩余天数计算 remain_days = db.Column(db.Integer, nullable=False, index=True, default=DEFAULT_MAX_REMAIN_DAYS) # 存储订单创建时间 created_at = db.Column(db.DateTime, default=datetime.utcnow) # 用户开始使用存储的时间 微信端点击入库时间 其实还没入库 requested_at = db.Column(db.DateTime, default=None) # 客服已经把箱子入库的时间 扣费也是根据这个时间算的 入库的时间 used_at = db.Column(db.DateTime, default=None) # 用户添加的备注信息 remark = db.Column(db.String(512), nullable=True) # 未寄回 STAGE_NOT_SEND_BACK = 1 # 已寄回 STAGE_SEND_BACK = 2 # 已销毁 STAGE_DESTROY = 3 # 查询全部状态 STAGE_ALL = 100 # 当前阶段 stage = db.Column(db.Integer, index=True, default=STAGE_NOT_SEND_BACK) # 未入库 STORAGE_NOT_PUT_IN = 0 # 已入库 STORAGE_PUT_IN = 1 # 查询全部状态 STORAGE_ALL = 100 # 入库状态 put_in_status = db.Column(db.Integer, index=True, default=STORAGE_NOT_PUT_IN) # 货架号 存储位置 goods_address = db.Column(db.String(64), default='') @classmethod def create(cls, user_id, mode_id, item_id): obj = cls(user_id=user_id, mode_id=mode_id, item_id=item_id) db.session.add(obj) db.session.commit() return obj def save(self): """Proxy method of saving object to database""" db.session.add(self) db.session.commit() @classmethod def get_multi_by_user(cls, user_id): return cls.query.filter_by(user_id=user_id).all() # 获得已经入库的箱子 @classmethod def get_used_coll_by_user(cls, user_id): return cls.query.filter_by(user_id=user_id, put_in_status=cls.STORAGE_PUT_IN).all() @classmethod def get(cls, id_): return cls.query.get(id_) # 分页查询 @classmethod def collection_paginate(cls, page, stage, put_in_status, size=10): # 已经被使用的订单 query = cls.query.filter(cls.status == cls.STATUS_USING) # 判断是否需要进行分状态查询 if hasattr(cls, 'stage') and stage != cls.STAGE_ALL: query = query.filter(cls.stage == stage) # 判断是否需要按入库状态查询 if hasattr(cls, 'put_in_status') and put_in_status != cls.STORAGE_ALL: query = query.filter(cls.put_in_status == put_in_status) # 按剩余天数排序 query = query.order_by('-remain_days') return query.paginate(page=page, per_page=size, error_out=False) # 获得所有数据量 @classmethod def get_collection_num(cls, stage, put_in_status): query = cls.query # 判断是否需要进行分状态查询 if hasattr(cls, 'stage') and stage != cls.STAGE_ALL: query = query.filter(cls.stage == stage) # 判断是否需要按入库状态查询 if hasattr(cls, 'put_in_status') and put_in_status != cls.STORAGE_ALL: query = query.filter(cls.put_in_status == put_in_status) return query.count() # 获得所有存储订单信息 @classmethod def get_collection_list(cls, page, stage, put_in_status, size=10): result_list = [] collection_list = cls.collection_paginate(page, stage, put_in_status, size) if collection_list is None: logger.warn("查询存储订单失败...") return result_list collection_list = collection_list.items if collection_list is None: logger.warn("存储订单list获取items字段失败...") return result_list for item in collection_list: result = { # 存储ID 'id': item.id, # 箱子编码 'item_id': item.item_id, # 订单时间 'requested_at': item.requested_at.strftime('%Y-%m-%d %H:%I:%S'), # 存储天数 'days': item.days, # 剩余天数 'remain_days': item.remain_days, # 用户姓名 'nickname': User.get_by_user_id(item.user_id).nickname, # 阶段 'stage': item.stage, # 仓库状态 'put_in_status': item.put_in_status, # 货架号 'goods_address': item.goods_address, # 'created_at': item.created_at.strftime('%Y-%m-%d %H:%I:%S'), # 'username': item.username, # 'mobile': item.mobile, # 'address': item.address, # 'box_num': item.box_num, # 'box_item': box_item, # 'status': item.status, # 'logistics_no': item.logistics_no, } # box_item_list = OrderItem.get_multi_by_order_id(item.id) # for b_item in box_item_list: # box_item.append(b_item.item_id) result_list.append(result) return result_list # 修改阶段状态 @classmethod def update_stage(cls, c_id, stage): if c_id is None or stage is None: return False, u'参数错误: c_id = {} stage = {}'.format(c_id, stage) collection = cls.query.get(c_id) if collection is None: return False, u'存储订单不存在!' collection.stage = stage collection.save() return True, u'success' # 删除订单 @classmethod def delete(cls, c_id): collection = cls.query.get(c_id) if collection is None: return False, u'存储订单不存在' db.session.delete(collection) db.session.commit() return True, u'success' # 入库操作 @classmethod def put_in(cls, c_id, goods_address): collection = cls.query.get(c_id) if collection is None: return False, u'存储订单不存在' total_fee = 0 # 入库地址修改 collection.goods_address = goods_address collection.days = 0 # 修改状态为入库状态 collection.put_in_status = cls.STORAGE_PUT_IN # 获得开始入库时间 collection.used_at = datetime.now() total_fee += Mode.get_mode_fee(collection.mode_id) # 开始计算剩余天数 # 找出已入库的数据信息 collection_list = cls.query.filter_by( put_in_status=cls.STORAGE_PUT_IN).all() # 获得余额 balance = Pocket.get_or_create_by_user_id(collection.user_id).balance for item in collection_list: total_fee += Mode.get_mode_fee(item.mode_id) # 获得剩余天数 collection.remain_days = balance // total_fee db.session.add(collection) for item in collection_list: item.remain_days = balance // total_fee db.session.add(collection) db.session.commit() return True, u'success' def as_resp(self): return { 'id': self.id, 'user_id': self.user_id, 'mode_id': self.mode_id, 'item_id': self.item_id, 'days': self.days, 'status': self.status, 'created_at': self.created_at.strftime('%Y-%m-%d %H:%I:%S'), 'requested_at': (self.requested_at.strftime('%Y-%m-%d') if self.requested_at else None), 'used_at': (self.used_at.strftime('%Y-%m-%d') if self.used_at else None), 'remark': self.remark, }
class Order(db.Model): __tablename__ = 'order' # 钱包支付方式 PAYED_CRASH = 'crash' # 微信支付方式 PAYED_WECHAT = 'wechat' # todo 未付款状态? STATUS_PENDING = 0 # # 账户付款 已付款状态 # STATUS_PAID_BY_CRASH = 1 # # 微信付款 已付款状态 # STATUS_PAID_BY_WECHAT = 2 # 已付款状态 STATUS_PAYED = 1 # 已发货状态 STATUS_SHIPMENTS = 2 # 取消订单 STATUS_CANCEL = 3 # 订单过期 STATUS_EXPIRED = 4 # 查询所有 STATUS_ALL = 100 id = db.Column(db.Integer, primary_key=True) # 哪个用户的订单 user_id = db.Column(db.Integer, nullable=False) # # 箱子订单的初始化地址信息ID address_id = db.Column(db.Integer, nullable=False) # 用户姓名 username = db.Column(db.String(32), nullable=False) # 手机 mobile = db.Column(db.String(16), nullable=False) # 邮寄地址 初始化时通过 用户传过来的地址id进行填充 address = db.Column(db.String(128), nullable=False) # 付款记录ID payment_id = db.Column(db.Integer, nullable=True) # 箱子的数目 box_num = db.Column(db.Integer, nullable=False) # 纸箱费用 不懂就看微信公众号怎么下单的 看付费细节 product_fee = db.Column(db.Integer, nullable=False) # 邮寄费用 好像还没用,下单的时候邮寄费用默认为0 express_fee = db.Column(db.Integer, nullable=False) # 物流编号 logistics_no = db.Column(db.String(128), default='') # todo 这个字段没有被使用过,不明白含义 expire_at = db.Column(db.DateTime, default=None) # 订单当前的付款状态 status = db.Column(db.Integer, index=True, default=STATUS_PENDING) # 付款方式 payment_method = db.Column(db.String(32), default='') created_at = db.Column(db.DateTime, default=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) @classmethod def create(cls, user_id, address_id, product_fee, express_fee, box_num=1): obj = cls(user_id=user_id, address_id=address_id, product_fee=product_fee, express_fee=express_fee, box_num=box_num) # 这里查询地址信息进行初始化 address = Address.get(address_id) obj.address = address.province + address.city + address.location # 用户名 obj.username = address.contact_name # 手机 obj.mobile = address.contact_phone obj.save() return obj def save(self): """Proxy method of saving object to database""" db.session.add(self) db.session.commit() @classmethod def delete(cls, order_id): order = cls.query.get(order_id) if order is None: return False, u'订单不存在' db.session.delete(order) db.session.commit() return True, u'success' # 通过付款记录获得订单信息 @classmethod def get_by_payment_id(cls, payment_id): return cls.query.filter_by(payment_id=payment_id).first() # 获得每个箱子的信息 def get_items(self): return OrderItem.get_multi_by_order_id(self.id) # 根据不同的状态进行分页查询 @classmethod def order_paginate(cls, page, status, size=10): query = cls.query # 判断是否需要进行分状态查询 if hasattr(cls, 'status') and status != cls.STATUS_ALL: query = query.filter(cls.status == status) return query.paginate(page=page, per_page=size, error_out=False) # 获得列表信息 @classmethod def get_order_list(cls, page, status, size=10): result_list = [] item_list = cls.order_paginate(page, status, size=size).items if item_list is None: return result_list for item in item_list: box_item = list() result = { 'id': item.id, 'created_at': item.created_at.strftime('%Y-%m-%d %H:%I:%S'), 'username': item.username, 'mobile': item.mobile, 'address': item.address, 'box_num': item.box_num, 'box_item': box_item, 'status': item.status, 'logistics_no': item.logistics_no, } box_item_list = OrderItem.get_multi_by_order_id(item.id) for b_item in box_item_list: box_item.append(b_item.item_id) result_list.append(result) return result_list # 查询订单数目 @classmethod def get_order_num(cls, status): # 查询全部 if status == cls.STATUS_ALL: return cls.query.count() return cls.query.filter_by(status=status).count() # 修改物流 @classmethod def update_logistics(cls, order_id, logistics_no): if order_id is None or logistics_no is None: return False, u'参数错误: order_id = {} logistics_no = {}'.format( order_id, logistics_no) order = cls.query.get(order_id) if order is None: return False, u'订单不存在!' # 判断订单状态是否正确 if order.status not in (cls.STATUS_PAYED, cls.STATUS_SHIPMENTS): return False, u'订单状态错误,无法修改物流信息: status = {}'.format(order.status) order.logistics_no = logistics_no order.save() return True, u'success' # 编辑订单 @classmethod def update_user_info(cls, order_id, username, mobile, address): if order_id is None: return False, u'订单号错误: order_id = {}'.format(order_id) order = cls.query.get(order_id) if order is None: return False, u'订单不存在!' if username is not None: order.username = username if mobile is not None: order.mobile = mobile if address is not None: order.address = address order.save() return True, u'success' def as_resp(self): items = self.get_items() return { 'id': self.id, 'express_fee': self.express_fee, 'product_fee': self.product_fee, 'items': [each.as_resp() for each in items] }