class Token(db.Model): id = db.Column(db.Integer, primary_key=True) create_time = db.Column(db.DateTime, default=datetime.datetime.now) # 首次创建时间,以服务器时间为准 user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 用户 id user = db.relationship('User', backref=db.backref('tokens', lazy='dynamic'), foreign_keys=[user_id]) token = db.Column(db.String(50), default=shortuuid.uuid) # 用户登陆后的临时唯一标识 device = db.Column(db.String(50)) # 设备 id
class Review(db.Model): # 用户晒单评论 id = db.Column(db.Integer, primary_key=True) valid = db.Column(db.Boolean, default=False) # 控制是否当作已删除处理(False 表示删除) selected = db.Column(db.Boolean, default=False) # 控制本文是否强制加入精选推荐 published = db.Column(db.Boolean, default=False) # 控制是否对外发布 publish_time = db.Column(db.DateTime, default=None) # 首次发布时间,以服务器时间为准 update_time = db.Column(db.DateTime, default=datetime.datetime.now) # 评论修改时间,以服务器时间为准 note = db.Column(db.Unicode(120), default=u'') # 晒单评论的后台运营备忘描述文字 create_user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 晒单评论信息创建人(有时后台运营人员会代替买手创建评论) create_user = db.relationship('User', backref=db.backref('created_reviews', lazy='dynamic'), foreign_keys=[create_user_id]) update_user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 晒单评论信息修改人(有时后台运营人员会代替买手创建评论) update_user = db.relationship('User', backref=db.backref('updated_reviews', lazy='dynamic'), foreign_keys=[update_user_id]) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 晒单评论的作者 user = db.relationship('User', backref=db.backref('reviews', lazy='dynamic'), foreign_keys=[user_id]) at_list = db.Column(db.String(200), default='') # 本评论将@的用户 id 列表,后端代码需要实现注意控制长度!多个 id 使用英文空格分隔。 stars = db.Column(db.Float, default=0.0) # POI 的评论星级,出于与统计结果,使用小数表示,实际只能是1~5 content = db.Column(db.UnicodeText) # 晒单评论的文本正文,只需分自然段,无需支持特殊格式。 images = db.Column(db.String(200), default='') # 晒单评论的附属图片的 id 列表,空格分隔。 keywords = db.Column(db.Unicode(200), default=u'') # 晒单评论关键词,空格分隔 total = db.Column(db.Float, default=0.0) # 本次购物总价 currency = db.Column(db.Unicode(10), default=u'') # 购物总价所对应的币种,这里没有做强制类别限制,需要在接收前端数据前作检查、判断 site_id = db.Column(db.Integer, db.ForeignKey('site.id')) # 关联的 POI site = db.relationship('Site', backref=db.backref('reviews', lazy='dynamic')) like_num = db.Column(db.Integer, default=0) # 喜欢本晒单的人数,这只是相当于一个缓存,实际数据根据“喜欢”的行为表计算得出 comment_num = db.Column(db.Integer, default=0) # 本晒单的评论总数,只是一个缓存值,实际数据根据“评论”的行为表计算得出 def __unicode__(self): return u'<Review [%d] %s: %s>' % (self.id, None if not self.user else self.user.name, self.update_time.strftime('%y-%m-%d'))
class Site(db.Model): # 店铺或景点等 POI id = db.Column(db.Integer, primary_key=True) valid = db.Column(db.Boolean, default=False) # 控制是否用户可见 order = db.Column(db.Integer, default=0) # 控制在前台的显示顺序,数字越大越靠前 note = db.Column(db.UnicodeText) # POI 的备忘描述文字 create_time = db.Column(db.DateTime, default=datetime.datetime.now) # 数据最初创建时间,以服务器时间为准 update_time = db.Column(db.DateTime, default=datetime.datetime.now) # 数据修改时间,以服务器时间为准 create_user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # POI 信息上传人 create_user = db.relationship('User', backref=db.backref('created_sites', lazy='dynamic'), foreign_keys=[create_user_id]) update_user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # POI 信息最后修改人 update_user = db.relationship('User', backref=db.backref('updated_sites', lazy='dynamic'), foreign_keys=[update_user_id]) code = db.Column(db.String(20), default='') # POI 的内部运营编号 name = db.Column(db.Unicode(80), default=u'') # POI 的名字 name_orig = db.Column(db.Unicode(80), default=u'') # POI 的当地文字原名 brand_id = db.Column(db.Integer, db.ForeignKey('brand.id')) # POI 所属品牌名称 brand = db.relationship('Brand', backref=db.backref('sites', lazy='dynamic')) logo_id = db.Column(db.Integer, db.ForeignKey('image.id')) # POI logo 首图的图片 id logo = db.relationship('Image') level = db.Column(db.Unicode(10), default=u'') # 用文字表示的 POI 质量等级,通常为 SS、S、A+、A 其中之一。 stars = db.Column(db.Float, default=0.0) # POI 的评论星级,由于是统计结果,因而存在半颗星等小数。 popular = db.Column(db.Integer, default=0) # 统计店铺人气指数,用于搜索排序,每天更新! review_num = db.Column(db.SmallInteger, default=0) # 该店铺拥有的晒单评论数量,是一个缓存值 categories = db.relationship('Category', lazy='dynamic', secondary=categories, backref=db.backref('sites', lazy='dynamic')) environment = db.Column(db.Unicode(50), default=u'') # 环境特点的文字描述 flowrate = db.Column(db.Unicode(20), default=u'') # 人流量情况 payment = db.Column(db.Unicode(50), default=u'') # 支持的支付方式 menu = db.Column(db.Unicode(20), default=u'') # 是否提供中文菜单 ticket = db.Column(db.UnicodeText) # 门票票价及购买方式,应支持换行 tour = db.Column(db.UnicodeText) # 导游等景点内组队的游览方式及参加价格,应支持换行 # ToDo: 这个字段在 app 前端可能暂未显示。 booking = db.Column(db.UnicodeText) # 预定方式,应支持换行 business_hours = db.Column(db.UnicodeText) # 营业时间描述,应支持换行,支持 {{text:id#注释}} 样式的标准文本替换 phone = db.Column(db.UnicodeText) # 联系电话 transport = db.Column(db.UnicodeText) # 公共交通的线路和站点文字描述,应支持换行 description = db.Column(db.UnicodeText) # POI 的简介描述 longitude = db.Column(Real, default=0.0) # 经度 latitude = db.Column(Real, default=0.0) # 纬度 # ToDo: 缺经纬度对应的方格坐标的缓存字段! area_id = db.Column(db.Integer, db.ForeignKey('area.id')) # 所属商区 area = db.relationship('Area', backref=db.backref('sites', lazy='dynamic')) mark = db.Column(db.UnicodeText) # 周围地标,支持换行 address = db.Column(db.UnicodeText) # POI 地址,应支持换行 address_orig = db.Column(db.UnicodeText) # POI 地址的当地文字版本,应支持换行 keywords = db.Column(db.Unicode(200), default=u'') # POI 关键词,可以认为是一个缓存,被 {} 括起来的是系统自动统计得到的,其他是运营人工设置。正常情况是使用空格分隔 top_images = db.Column(db.String(500), default='') # 热门图片的 id 列表,英文空格分隔 images_num = db.Column(db.SmallInteger, default=0) # 该店铺拥有的晒单评论相关图片数量,是一个缓存值 gate_images = db.Column(db.String(100), default='') # 店铺门脸展示图片的 id 列表,英文空格分隔 data_source = db.Column(db.Unicode(500), default=u'') # 本 POI 数据采集的原始网址 def __unicode__(self): return u'<Site [%d] {%s} %s>' % (self.id, self.code, self.name)
class Image(db.Model): # 全局图片存储 id = db.Column(db.Integer, primary_key=True) valid = db.Column(db.Boolean, default=True) # 控制是否当作已删除处理(False 表示删除) type = db.Column(db.SmallInteger, default=1) # 图片分类:1 表示店铺 logo;2 表示店铺门脸图;3 表示用户头像;4 表示评论图片。 path = db.Column(db.String(120), default='') # 图片所在存储路径 note = db.Column(db.Unicode(120), default=u'') # 图片的备忘描述文字 create_time = db.Column(db.DateTime, default=datetime.datetime.now) # 图片上传时间,以服务器时间为准 user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 图片上传人 user = db.relationship('User', backref=db.backref('images', lazy='dynamic'), foreign_keys=[user_id]) name = db.Column(db.Unicode(80), default=u'') # 图片的原始文件名 size = db.Column(db.Integer, default=0) # 图片的存储大小,单位是 Byte mime = db.Column(db.String(50), default='') # 图片的原始 mime 信息 width = db.Column(db.SmallInteger, default=0) # 图片原始宽度 height = db.Column(db.SmallInteger, default=0) # 图片原始高度 def __unicode__(self): return u'<Image [%d] %s>' % (self.id, 'None' if not self.path else self.path.split('/')[-1])
class City(db.Model): # 城市 id = db.Column(db.Integer, primary_key=True) valid = db.Column(db.Boolean, default=False) # 控制是否用户可见 order = db.Column(db.Integer, default=0) # 控制在前台的显示顺序,数字越大越靠前 name = db.Column(db.Unicode(20), default=u'') # 城市名称 longitude = db.Column(Real, default=0.0) # 城市中心点,经度 latitude = db.Column(Real, default=0.0) # 城市中心点,纬度 timezone = db.Column(db.String(20), default='') # 城市对应的时区,用于决定天气预报数据更新时间 country_id = db.Column(db.Integer, db.ForeignKey('country.id')) country = db.relationship('Country', backref=db.backref('cities', lazy='dynamic'), foreign_keys=[country_id]) def __unicode__(self): return u'<City [%d] %s>' % (self.id, self.name)
class Comment(db.Model): # 用户子评论 id = db.Column(db.Integer, primary_key=True) valid = db.Column(db.Boolean, default=False) # 控制是否当作已删除处理(False 表示删除) publish_time = db.Column(db.DateTime, default=datetime.datetime.now) # 首次发布时间,以服务器时间为准 update_time = db.Column(db.DateTime, default=datetime.datetime.now) # 评论修改时间,以服务器时间为准 review_id = db.Column(db.Integer, db.ForeignKey('review.id')) # 子评论所关联的晒单评论 review = db.relationship('Review', backref=db.backref('comments', lazy='dynamic')) article_id = db.Column(db.Integer, db.ForeignKey('article.id')) # 子评论所关联的首页文章 article = db.relationship('Article', backref=db.backref('comments', lazy='dynamic')) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 评论的作者 user = db.relationship('User', backref=db.backref('comments', lazy='dynamic')) at_list = db.Column(db.String(200), default='') # 本评论将@的用户 id 列表,通常子评论只能@一个人,也就是所回复的子评论的原作者 content = db.Column(db.UnicodeText) # 评论的文字正文,需要注意检查内容长度 def __unicode__(self): return u'<Comment [%d] %s: %s>' % (self.id, None if not self.user else self.user.name, self.update_time.strftime('%y-%m-%d'))
class ShareRecord(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 进行共享的人 user = db.relationship('User', backref=db.backref('share_records', lazy='dynamic'), foreign_keys=[user_id]) article_id = db.Column(db.Integer, db.ForeignKey('article.id')) # 如果被共享的是首页文章,则在这里做绑定 article = db.relationship('Article') site_id = db.Column(db.Integer, db.ForeignKey('site.id')) # 如果被共享的是店铺,则在这里做绑定 site = db.relationship('Site') review_id = db.Column(db.Integer, db.ForeignKey('review.id')) # 如果被共享的是晒单评论,则在这里做绑定 review = db.relationship('Review') target = db.Column(db.Unicode(20), default=u'') # 用户分享的目的地,比如微信或短信,中文文字描述 action_time = db.Column(db.DateTime, default=datetime.datetime.now) # 用户分享文章或店铺的时间点 token = db.Column(db.String(50), default=shortuuid.uuid) # 从外网访问被分享内容的唯一访问标识 def __unicode__(self): return u'<ShareRecord [%d] %s: site %d, review %d>' % (self.id, None if not self.user else self.user.name, self.site_id or -1, self.review_id or -1)
class User(db.Model): id = db.Column(db.Integer, autoincrement='ignore_fk', primary_key=True) valid = db.Column(db.Boolean, default=True) # 控制是否当作已删除处理(False 表示删除) anonymous = db.Column(db.Boolean, default=False) # 表示是否是系统自动生成的非注册用户 create_time = db.Column(db.DateTime, default=datetime.datetime.now) # 首次创建时间,以服务器时间为准 update_time = db.Column(db.DateTime, default=datetime.datetime.now) # 用户属性信息修改时间,以服务器时间为准 name = db.Column(db.Unicode(100), unique=True) # 可见用户昵称。注:由于设置了 unique ,所以未填本项的都保留为 null 。 username = db.Column(db.String(80), unique=True, default='') # 登陆用用户名,App 端会是设备 id(匿名用户)或手机号(已注册用户) mobile = db.Column(db.String(120), unique=True) # 用户手机号。注:由于设置了 unique ,所以未填本项的都保留为 null 。 password = db.Column(db.String(80), default='') # Hash 处理之后的登陆密码 em_username = db.Column(db.String(80), unique=True, default=None) # 环信用户账号,通常是随机生成的 UUID em_password = db.Column(db.String(80), default=None) # 环信用户密码的明文,通常也是随机生成的 UUID icon_id = db.Column(db.Integer, db.ForeignKey('image.id', use_alter=True, name='fk_icon')) # 用户头像的图片 id icon = db.relationship('Image', foreign_keys=[icon_id], post_update=True) gender = db.Column(db.Unicode(10), default=u'未知') # 用户填写的性别参数:男、女、未知 level = db.Column(db.SmallInteger, default=1) # 用数字表示的用户等级 exp = db.Column(db.Integer, default=0) # 与用户等级对应的用户经验,需要根据每天的行为日志做更新 follow_num = db.Column(db.SmallInteger, default=0) # 该用户已关注的账号的数量,是一个缓存值 fans_num = db.Column(db.SmallInteger, default=0) # 该用户拥有的粉丝数量,是一个缓存值 fans = db.relationship('User', lazy='dynamic', secondary=fans, primaryjoin=id==fans.c.user_id, secondaryjoin=id==fans.c.fan_id, backref=db.backref('follows', lazy='dynamic')) like_num = db.Column(db.SmallInteger, default=0) # 该用户喜欢的晒单评论数量,是一个缓存值 likes = db.relationship('Review', lazy='dynamic', secondary=likes, backref=db.backref('fans', lazy='dynamic')) share_num = db.Column(db.SmallInteger, default=0) # 该用户的分享行为数量,是一个缓存值 review_num = db.Column(db.SmallInteger, default=0) # 该用户发表的晒单评论数量,是一个缓存值 favorite_num = db.Column(db.SmallInteger, default=0) # 该用户收藏的店铺的数量,是一个缓存值 favorites = db.relationship('Site', lazy='dynamic', secondary=favorites, backref=db.backref('fans', lazy='dynamic')) badges = db.Column(db.Unicode(500), default=u'') # 用户拥有的徽章名称列表 roles = db.relationship('Role', lazy='dynamic', secondary=roles_users, backref=db.backref('users', lazy='dynamic')) # ToDo: 勋章内容的更新机制暂未实现! def is_admin(self): check = False for role in self.roles: if role.id == 7: check = True return check and self.valid def is_operator(self): check = False for role in self.roles: if role.id == 8: check = True return check and self.valid # Flask-Login integration def is_authenticated(self): return self.valid and not self.anonymous def is_active(self): return self.valid def is_anonymous(self): return not self.valid or self.anonymous def get_id(self): return self.id # Required for administrative interface def __unicode__(self): return u'<User [%d] %s>' % (self.id, self.name)